2  Command-Line Arguments

Does it bother you that all shell scripts look alike? Then you're on your way to good programming. Remember that good programmers recognize repeated patterns and try to abstract over them.8

Let's write the shell script make-script, which produces a shell script from a Scheme file name and an initial expression. For example,

   > make-script addparens.ss "(add-parens-to-file)"

produces the script in figure [***]. Similarly,

   > make-script grades.ss "(pretty-print ...)"

writes the grade script on page 13.

Clearly, writing this program means that we need one big string constant, four lines long:

The tricky part about this string is that it must contain an string-quoted element: "DOLLAR@". To accomplish this we need to use ``' Scheme's escape character in front of the embedded string quotes. Otherwise, this string is basically just the pattern of a shell script that we encountered over and over again. It contains two formatting characters: ~s and ~a. The former is a placeholder for the file name, the latter stands for the expression.

The interesting question with regard to script is how it can get hold of these two arguments, which are passed on the command line. For this, MzScheme borrows an old trick from the Unix world: the argv vector. This vector contains all elements from the command line as strings. Thus, if the command line looks like this

   > make-script addparens.ss "(add-parens-to-file)"

argv contains "addparens.ss" in slot 0 and "(add-parens-to-file)" in slot 1.

Now it is easy to write the rest of the program. Here it is, as a one-liner:

(printf SCRIPT-TEMPLATE (vector-ref argv 0) (vector-ref argv 1))

Of course, we would also add a line that checks whether the vector contains enough elements:

(unless (= (vector-length argv) 2)
  (printf "script: wrong number of arguments.~n")
  (printf "proper format: script <filename> <S-expression>~n")
  (error 'script "Bye."))

But we leave that kind of reasoning to the next section, where we write our final version of addparens.


8 Okay, we are not the first ones to notice these similarities. The launcher script in

  @PLTHOME/collects/launcher/@  
provides the same service, but it is good to know how to write such scripts in general.