Path: utzoo!utgpu!water!watmath!clyde!att!ucbvax!husc6!rice!titan!dorai From: dorai@titan.rice.edu (Dorai Sitaram) Newsgroups: comp.lang.scheme Subject: Re: Scheme shellscripts Summary: Solution with #! Message-ID: <1700@kalliope.rice.edu> Date: 20 Jul 88 21:00:41 GMT References: <1666@kalliope.rice.edu> <880716144458.6.JAMES@GREEN-GRASS.LCS.MIT.EDU> Sender: usenet@rice.edu Reply-To: dorai@titan.rice.edu (Dorai Sitaram) Organization: Rice University, Houston Lines: 116 James William O'Toole Jr. 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 ******************************************** 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