Running Command Scripts

Unix-like systems support a mechanism where a script can specify a program that should execute it. The convention is that the first line of the file should start with the two characters ‘#!’ followed by the absolute path of the program that should process (interpret) the script.

This is convention works well for script languages that use ‘#’ to indicate the start of a comment, since the interpreter will automatically ignore the line specifying the interpreter filename. Scheme, however, uses ‘#’ for various special objects, and Kawa specifically uses ‘#!’ as a prefix for various Special named constants such as #!optional.

Kawa does recognize the three-character sequence ‘#!/’ at the beginning of a file as special, and ignores it. So you can specify command interpreters, as long as you don't put a space between the ‘#!’ and the interpreter filename. Here is an example:

#!/usr/local/bin/kawa
(format #t "The time is ~s~%" (make <java.util.Date>))

If this file has the execute permission set and is in your PATH, then you can execute it just by naming it on command line. The system kernel will automatically execute kawa, passing it the filename as an argument.

Note that the full path-name of the kawa interpreter must be hard-wired into the script. This means you may have to edit the script depending on where Kawa is installed on your system. Another possible problem is that the interpreter must be an actual program, not a shell script. Depending on how you configure and install Kawa, kawa can be a real program or a script. You can avoid both problems by the env program, available on most modern Unix-like systems:

#!/usr/bin/env kawa
(format #t "The time is ~s~%" (make <java.util.Date>))

If you need to specify extra arguments to kawa, you can use the following trick:

#!/bin/sh
exec kawa --commonlisp out:base=16 --script2 "$0" "$@"
(setq xx 20) (display xx) (newline)

This causes the shell to invoke the kawa program. This assumes kawa is in the command path; if not replace kawa by the appropriate incantation, which can be multiple words (for example java kawa.repl). The exec tells the shell to replace itself by kawa; this is important so the shell doesn't continue with this file when done with kawa. The rest of the line can contain whatever commands and options you want when executing Kawa. The important part is --script2 "$0". The shell replaces the "$0" by the name the script, and replaces the "$@" by the remaining arguments passed to the script. So what Kawa sees is the --script2 option followed the script name, followed by remaining command-line arguments. The --script2 tells Kawa to execute the script, after ignoring the initial two lines, which would confuse it terribly.