Previous: Filenames, Up: Programs and Arguments


4.4.7 Batch

(require 'batch) The batch procedures provide a way to write and execute portable scripts for a variety of operating systems. Each batch: procedure takes as its first argument a parameter-list (see Parameter lists). This parameter-list argument parms contains named associations. Batch currently uses 2 of these:

batch-port
The port on which to write lines of the batch file.
batch-dialect
The syntax of batch file to generate. Currently supported are:

The ‘batch’ module uses 2 enhanced relational tables (see Using Databases) to store information linking the names of operating-systems to batch-dialectes.

— Function: batch:initialize! database

Defines operating-system and batch-dialect tables and adds the domain operating-system to the enhanced relational database database.

— Variable: *operating-system*

Is batch's best guess as to which operating-system it is running under. *operating-system* is set to (software-type) (see Configuration) unless (software-type) is unix, in which case finer distinctions are made.

— Function: batch:call-with-output-script parms file proc

proc should be a procedure of one argument. If file is an output-port, batch:call-with-output-script writes an appropriate header to file and then calls proc with file as the only argument. If file is a string, batch:call-with-output-script opens a output-file of name file, writes an appropriate header to file, and then calls proc with the newly opened port as the only argument. Otherwise, batch:call-with-output-script acts as if it was called with the result of (current-output-port) as its third argument.

The rest of the batch: procedures write (or execute if batch-dialect is system) commands to the batch port which has been added to parms or (copy-tree parms) by the code:

     (adjoin-parameters! parms (list 'batch-port port))
— Function: batch:command parms string1 string2 ...

Calls batch:try-command (below) with arguments, but signals an error if batch:try-command returns #f.

These functions return a non-false value if the command was successfully translated into the batch dialect and #f if not. In the case of the system dialect, the value is non-false if the operation suceeded.

— Function: batch:try-command parms string1 string2 ...

Writes a command to the batch-port in parms which executes the program named string1 with arguments string2 ....

— Function: batch:try-chopped-command parms arg1 arg2 ... list

breaks the last argument list into chunks small enough so that the command:

          arg1 arg2 ... chunk

fits withing the platform's maximum command-line length.

batch:try-chopped-command calls batch:try-command with the command and returns non-false only if the commands all fit and batch:try-command of each command line returned non-false.

— Function: batch:run-script parms string1 string2 ...

Writes a command to the batch-port in parms which executes the batch script named string1 with arguments string2 ....

Note: batch:run-script and batch:try-command are not the same for some operating systems (VMS).

— Function: batch:comment parms line1 ...

Writes comment lines line1 ... to the batch-port in parms.

— Function: batch:lines->file parms file line1 ...

Writes commands to the batch-port in parms which create a file named file with contents line1 ....

— Function: batch:delete-file parms file

Writes a command to the batch-port in parms which deletes the file named file.

— Function: batch:rename-file parms old-name new-name

Writes a command to the batch-port in parms which renames the file old-name to new-name.

In addition, batch provides some small utilities very useful for writing scripts:

— Function: truncate-up-to path char
— Function: truncate-up-to path string
— Function: truncate-up-to path charlist

path can be a string or a list of strings. Returns path sans any prefixes ending with a character of the second argument. This can be used to derive a filename moved locally from elsewhere.

          (truncate-up-to "/usr/local/lib/slib/batch.scm" "/")
          ⇒ "batch.scm"
— Function: string-join joiner string1 ...

Returns a new string consisting of all the strings string1 ... in order appended together with the string joiner between each adjacent pair.

— Function: must-be-first list1 list2

Returns a new list consisting of the elements of list2 ordered so that if some elements of list1 are equal? to elements of list2, then those elements will appear first and in the order of list1.

— Function: must-be-last list1 list2

Returns a new list consisting of the elements of list1 ordered so that if some elements of list2 are equal? to elements of list1, then those elements will appear last and in the order of list2.

— Function: os->batch-dialect osname

Returns its best guess for the batch-dialect to be used for the operating-system named osname. os->batch-dialect uses the tables added to database by batch:initialize!.

Here is an example of the use of most of batch's procedures:

     (require 'databases)
     (require 'parameters)
     (require 'batch)
     (require 'filename)
     
     (define batch (create-database #f 'alist-table))
     (batch:initialize! batch)
     
     (define my-parameters
       (list (list 'batch-dialect (os->batch-dialect *operating-system*))
             (list 'operating-system *operating-system*)
             (list 'batch-port (current-output-port)))) ;gets filled in later
     
     (batch:call-with-output-script
      my-parameters
      "my-batch"
      (lambda (batch-port)
        (adjoin-parameters! my-parameters (list 'batch-port batch-port))
        (and
         (batch:comment my-parameters
                        "================ Write file with C program.")
         (batch:rename-file my-parameters "hello.c" "hello.c~")
         (batch:lines->file my-parameters "hello.c"
                            "#include <stdio.h>"
                            "int main(int argc, char **argv)"
                            "{"
                            "  printf(\"hello world\\n\");"
                            "  return 0;"
                            "}" )
         (batch:command my-parameters "cc" "-c" "hello.c")
         (batch:command my-parameters "cc" "-o" "hello"
                       (replace-suffix "hello.c" ".c" ".o"))
         (batch:command my-parameters "hello")
         (batch:delete-file my-parameters "hello")
         (batch:delete-file my-parameters "hello.c")
         (batch:delete-file my-parameters "hello.o")
         (batch:delete-file my-parameters "my-batch")
         )))

Produces the file my-batch:

     #! /bin/sh
     # "my-batch" script created by SLIB/batch Sun Oct 31 18:24:10 1999
     # ================ Write file with C program.
     mv -f hello.c hello.c~
     rm -f hello.c
     echo '#include <stdio.h>'>>hello.c
     echo 'int main(int argc, char **argv)'>>hello.c
     echo '{'>>hello.c
     echo '  printf("hello world\n");'>>hello.c
     echo '  return 0;'>>hello.c
     echo '}'>>hello.c
     cc -c hello.c
     cc -o hello hello.o
     hello
     rm -f hello
     rm -f hello.c
     rm -f hello.o
     rm -f my-batch

When run, my-batch prints:

     bash$ my-batch
     mv: hello.c: No such file or directory
     hello world