In reading this section, keep in mind that the first line of a script
file has (different) meanings to SCM and the operating system
On unix systems, a Shell-Script is a file (with execute
permissions) whose first two characters are ‘#!’. The
interpreter argument must be the pathname of the program to
process the rest of the file. The directories named by environment
PATH are not searched to find interpreter.
When executing a shell-script, the operating system invokes interpreter with a single argument encapsulating the rest of the first line’s contents (if not just whitespace), the pathname of the Scheme Script file, and then any arguments which the shell-script was invoked with.
Put one space character between ‘#!’ and the first character of interpreter (‘/’). The interpreter name is followed by ‘ \’; SCM substitutes the second line of file for ‘\’ (and the rest of the line), then appends any arguments given on the command line invoking this Scheme-Script.
When SCM executes the script, the Scheme variable *script* will be set to the script pathname. The last argument before ‘!#’ on the second line should be ‘-’; SCM will load the script file, preserve the unprocessed arguments, and set *argv* to a list of the script pathname and the unprocessed arguments.
Note that the interpreter, not the operating system, provides the ‘\’ substitution; this will only take place if interpreter is a SCM or SCSH interpreter.
When the first two characters of the file being loaded are
a ‘\’ is present before a newline in the file, all characters up
to ‘!#’ will be ignored by SCM
This combination of interpretatons allows SCM source files to be used as POSIX shell-scripts if the first line is:
#! /usr/local/bin/scm \
The following Scheme-Script prints factorial of its argument:
#! /usr/local/bin/scm \ %0 %* - !# (define (fact.script args) (cond ((and (= 1 (length args)) (string->number (car args))) => (lambda (n) (print (fact n)) #t)) (else (fact.usage)))) (define (fact.usage) (print *argv*) (display "\ Usage: fact N Returns the factorial of N. " (current-error-port)) #f) (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) (if *script* (exit (fact.script (list-tail *argv* *optind*))))
./fact 32 ⇒ 263130836933693530167218012160000000
If the wrong number of arguments is given,
fact prints its
argv with usage information.
./fact 3 2 -| ("./fact" "3" "2") Usage: fact N Returns the factorial of N.