► |  | Guide: PLT Scheme

1 | Welcome to PLT Scheme
2 | Scheme Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units (Components)
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Performance
18 | Running and Creating Executables
19 | Compilation and Configuration
20 | More Libraries
21 | Dialects of Scheme
| Bibliography
| Index

▼ | 18 | Running and Creating Executables

18.1 | Running mzscheme and mred
18.2 | Unix Scripts
18.3 | Creating Stand-Alone Executables

Version: 4.1.4
top← prev up next →

#### 18.2`` Unix Scripts

Under Unix and Mac OS X, a Scheme file can be turned into an executable script using the shell’s #! convention. The first two characters of the file must be #!; the next character must be either a space or /, and the remainder of the first line must be a command to execute the script. For some platforms, the total length of the first line is restricted to 32 characters, and sometimes the space is required.

The simplest script format uses an absolute path to a mzscheme executable followed by a module declaration. For example, if mzscheme is installed in "/usr/local/bin", then a file containing the following text acts as a “hello world” script:

#! /usr/local/bin/mzscheme
#lang scheme/base
"Hello, world!"

In particular, if the above is put into a file "hello" and the file is made executable (e.g., with chmod a+x hello), then typing ./hello at the shell prompt produces the output "Hello, world!".

The above script works because the operating system automatically puts the path to the script as the argument to the program started by the #! line, and because mzscheme treats a single non-flag argument as a file containing a module to run.

Instead of specifying a complete path to the mzscheme executable, a popular alternative is to require that mzscheme is in the user’s command path, and then “trampoline” using /usr/bin/env:

#! /usr/bin/env mzscheme
#lang scheme/base
"Hello, world!"

In either case, command-line arguments to a script are available via current-command-line-arguments:

#! /usr/bin/env mzscheme
#lang scheme/base
(printf "Given arguments: ~s\n"
(current-command-line-arguments))

If the name of the script is needed, it is available via (find-system-path 'run-file), instead of via (current-command-line-arguments).

Usually, then best way to handle command-line arguments is to parse them using the command-line form provided by scheme. The command-line form extracts command-line arguments from (current-command-line-arguments) by default:

#! /usr/bin/env mzscheme
#lang scheme
(define verbose? (make-parameter #f))
(define greeting
(command-line
#:once-each
[("-v") "Verbose mode" (verbose? #t)]
#:args
(str) str))
(printf "~a~a\n"
greeting
(if (verbose?) " to you, too!" ""))

Try running the above script with the --help flag to see what command-line arguments are allowed by the script.

An even more general trampoline uses /bin/sh plus some lines that are comments in one language and expressions in the other. This trampoline is more complicated, but it provides more control over command-line arguments to "mzscheme":

#! /bin/sh
#|
exec mzscheme -cu "$0" ${1+"$@"}
|#
#lang scheme/base
(printf "This script started slowly, because the use of\n")
(printf "bytecode files has been disabled via -c.\n")
(printf "Given arguments: ~s\n"
(current-command-line-arguments))

Note that #! starts a line comment in Scheme, and #|...|# forms a block comment. Meanwhile, # also starts a shell-script comment, while exec mzscheme aborts the shell script to start mzscheme. That way, the script file turns out to be valid input to both /bin/sh and mzscheme.

top← prev up next →