James William O'Toole Jr. <james@ZERMATT.LCS.MIT.EDU> writes:
> Date: 16 Jul 88 08:01:32 GMT
> From: titan!dorai@rice.edu (Dorai Sitaram)
>
> A shellscript written in Scheme is like any other Scheme file, except that its
> first line has to be:
> runschemescript "$*" '
> and its last line:
> '
>
> The quotes are used to delimit the Scheme code which forms the body of the
> script. The script consists of a call of the Un*x command `runschemescript'
> with two arguments, the first being the list of arguments to the Scheme
> script, and the second the text of the Scheme code in the script. Thus, a
> Scheme shellscript is a *true* schellscript, i.e., it is callable at the Un*x
> command-line, though the main part of it is a piece of text which is Scheme.
>
> The command `runschemescript' used above is a shellscript written in the usual
> shell language. It is the following relatively simple piece of cshell:
>
> ...
>
> If anyone can suggest further improvement I'll be glad to hear of it.
>
>Your method, when executed, requires starting one /bin/csh to interpret
>the shellscript, another /bin/csh to interpret the ``runschemescript''
>shellscript, copying the scheme code into a temporary file, and invoking
>the scheme implementation on that file.
>
>I would suggest that you instead place your scheme code in a file whose
>first line is ``#!/bin/scheme arg''. If your file is called foo, and
>its first line is as given above, then when you execute foo, your Unix
>will execute the command ``/bin/scheme arg foo''. You may omit arg, or
>choose arg to be something which speeds up /bin/scheme, or tells it to
>load the file whose name follows, or whatever. You will have to
>convince your scheme to ignore the first line of foo, of course. This
>method avoids starting up extra shells and copying files.
>
> --Jim
A Refresher on #!
-----------------
If `#! A A1 ...' is the first line of a shell script file whose name is B,
calling B with args B1 ... has the same effect as calling A with args
A1 ... B B1 ...
In the above, A has to be a full pathname of a *standard* Un*x command (like
cat, scheme, etc), i.e., it cannot be a user-fashioned command or shell script
(I found this out thru experimentation. Why is this?).
!# no rehserfeR A
-----------------
Jim [and J A Biep Durieux (private communication)] suggest that
#! /usr/local/scheme be the first line of a Scheme script: this has the
unfortunate effect that all arguments to a Scheme script will be loaded as
Scheme files [even though they are in general, just like any shell script
arguments, *not* Scheme files]. The script file itself is loaded into Scheme,
which is ok, provided that its first (non-Scheme) line can somehow be removed.
However, Jim and Biep are right in stating that #! can lead to a concise
and efficient implementation of Scheme scripts. Let the first line of a
Scheme script be the line
#! /bin/sh runschemescript
runschemescript is a Bourne script which looks like:
********************************************
foo=$1
shift
echo > .tmp '(set! $* (quote ('$*')))'
echo -n >> .tmp ';'
cat $foo >> .tmp
echo >> .tmp '(exit)'
scheme .tmp #this line could be 'exec scheme .tmp' but I don't know if
#that saves anything
********************************************
A Scheme script 'ss' looks like:
********************************************
#! /bin/sh runschemescript
<a body of Scheme code which
refers to the list of arguments
of `ss' by the variable $*>
********************************************
This Scheme code doesn't have the restriction of not being able to use quotes
in it. It also looks less ugly with the user not having to mention $* and use
Bourne quotes in his Scheme scripts.
ss, when called with arguments a1 ..., gets converted (by the #!) to the call
/bin/sh runschemescript ss a1 ...
which is the same as (with one subshell invocation)
runschemescript ss a1 ...
runschemescript then creates a .tmp file which sets a Scheme global variable
$* to a list (a1 ...) of ss's arguments; followed by the contents of the file
ss; followed by an (exit). [A judicious ';' is inserted at the right spot to
comment out the only non-Scheme portion of the file ss: the first line (with
#! ...).] ss can therefore be used as a regular shell script which is written
in Scheme rather than in Bourne.
I would like the first line of Scheme script to be just
#! runschemescript
instead of
#! /bin/sh runschemescript
but as said earlier, only standard Un*x commands seem to be accepted by #!.
Improvements are welcome.
--dorai