PREV UP next SCM

3.12.3: MS-DOS Compatible Scripts

It turns out that we can create shell-scripts which run both under unix and MS-DOS. To implement this, I have written the MS-DOS programs: #!.bat and !#.exe.

With these two programs installed in a PATH directory, we have the following syntax for <program>.BAT files.

file: #! interpreter \ %0 %1 %2 %3 %4 %5 %6 %7 %8

The first two characters of the shell-script are `#!'. The interpreter can be either a unix style program path (using `/' between filename components) or a DOS program name or path. The rest of the first line of the shell-script should be literally `\ %0 %1 %2 %3 %4 %5 %6 %7 %8', as shown.

If interpreter has `/' in it, interpreter is converted to a DOS style filename (`/' => `\').

In looking for an executable named interpreter, #! first checks this (converted) filename; if interpreter doesn't exist, it then tries to find a program named like the string starting after the last `\' (or `/') in interpreter. When searching for executables, #! tries all directories named by environment variable PATH.

Once the interpreter executable path is found, arguments are processed in the manner of scheme-shell, with the all the text after the `\' taken as part of the meta-argument. More precisely, #! calls interpreter with any options on the second line of the shell-script up to `!#', the name of the shell-script file, and then any of at most 8 arguments given on the command line invoking this shell-script.

The following shell-script will print its expanded argument list, then factorial of its argument. This shell-script in both MS-DOS and unix systems.

#! /usr/local/bin/scm \ %0 %1 %2 %3 %4 %5 %6 %7 %8
 -p1 -l !#
(print (program-arguments))
(define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n)))))
(print (fact (string->number (list-ref (program-arguments) *optind*))))