scsh-0.5/doc/scsh-manual/running.tex

225 lines
9.2 KiB
TeX

%&latex -*- latex -*-
\chapter{Running scsh}
Scsh is currently implemented on top of {\scm}, a freely-available
{\Scheme} implementation written by Jonathan Rees and Richard Kelsey.
{\scm} uses a byte-code interpreter for good code density, portability
and medium efficiency. It is {\R4RS}. The version on top of which scsh is
currently built (0.36) lacks floating point.
It also has a module system designed by Jonathan Rees.
Scsh's design is not {\scm} specific, although the current implementation
is necessarily so. Scsh is intended to be implementable in other {\Scheme}
implementations---although such a port may require some work.
The {\scm} vm that scsh uses is a specially modified version;
standard {\scm} virtual machines cannot be used with the scsh heap image.
To run the {\scm} implementation of scsh, you run a specially modified
copy of the {\scm} virtual machine with a scsh heap image.
This command starts the vm up with a 1Mword heap (split into two semispaces):
\codex{scshvm -o scshvm -h 1000000 -i scsh.image arg1 arg2 \ldots}
The vm peels off initial vm arguments
up to the \ex{-i} heap image argument, which terminates vm argument parsing.
The rest of the arguments are passed off to the scsh top-level.
Scsh's top-level removes scsh arguments; the rest show up as the value
of \ex{command-line-arguments}.
Alternatively, you can run the scsh top-level binary.
This is nothing but a small cover program that invokes the
scsh vm on the scsh heap image for you.
This allows you to simply start up an interactive scsh from a command
line, as well as write shell scripts that begin with the simple trigger
\codex{\#!/usr/local/bin/scsh -s}
\section{VM arguments}
\label{sec:vm-args}
Scsh uses a special version of the {\scm} virtual machine.
It takes arguments in the following form:
\codex{scshvm [\var{meta-arg}] [\var{vm-options}\+] [\var{end-option} \var{scheme-args}]}
where
\begin{inset}
\begin{tabular}{ll}
\var{meta-arg:} & \verb|\ |\var{script} \\
\\
\var{vm-option}: & \ex{-h }\var{heap-size-in-words} \\
& \ex{-s }\var{stack-size-in-words} \\
& \ex{-o }\var{object-file-name} \\
\\
\var{end-option:} & \ex{-i }\var{image-file-name} \\
& \ex{--}
\end{tabular}
\end{inset}
\subsection{The meta argument}
The {\scm} vm takes a special command-line switch, a single backslash called
the ``meta-switch,'' which is useful for shell scripts.
While parsing the command-line arguments, if the vm sees a ``\verb|\|''
argument, followed by a filename argument \var{fname}, it will open the file
\var{fname}, and read more arguments from the second line of this file.
This list of arguments will then replace the ``\verb|\|'' argument---\ie,
the new arguments are inserted in front of \var{fname},
and the argument parser resumes argument scanning.
This is used to overcome a limitation of the \ex{\#!} feature:
the \ex{\#!} line can only specify a single argument after the interpreter.
For example, we might hope the following scsh script, \ex{ekko},
would implement a simple-minded version of \ex{echo(1)}:
\begin{code}
#!/bin/scshvm -o /bin/scshvm -i /lib/scsh.image -s
!#
(map (\l{arg} (display arg) (display " "))
command-line-arguments)
(newline)\end{code}
%
The idea would be that the command
\codex{ekko Hi there.}
would by expanded by \ex{exec(2)} into
%
\begin{code}
/bin/scshvm -o /bin/scshvm -i /lib/scsh.image -s ekko Hi there.\end{code}
%
In theory, this would cause scsh to start up, set \ex{command-line-arguments}
to \ex{("Hi" "there.")}, load the source file \ex{ekko}, and exit.
However, the {\Unix} \ex{exec(2)} call will not handle multiple arguments
on the \ex{\#!} line, so this script won't work. We must instead invoke
the {\scm} vm with the single \cd{\\} argument, and put the rest of the
arguments on line two of the script. Here's the correct script:\footnote{
In fact, I'm playing fast and loose with the actual pathnames
used in this example: \ex{scshvm} is probably not going to be found in
\ex{/bin}. I've abbreviated things so the long argument lists will fit
into one line of text.
See the following sections for the full details.}
%
\begin{code}
#!/bin/scshvm \\
-o /bin/scshvm -i /lib/scsh.image -s
!#
(map (\l{arg} (display arg) (display " "))
command-line-arguments)
(newline)\end{code}
%
Now, the invocation starts as
\codex{ekko Hi there.}
and is expanded by exec(2) into
\begin{code}
/bin/scshvm \\ ekko Hi there.\end{code}
When scshvm starts up, it expands the ``\cd{\\}'' argument into the arguments
read from line two of \ex{ekko}, producing this argument list:
\begin{code}\cddollar
\underline{-o /bin/scshvm -i /lib/scsh.image -s ekko} Hi there.
$\uparrow$
{\rm{}Expanded from} \cd{\\} ekko\end{code}
%
With this argument list, processing proceeds as we intended.
\subsection{VM options}
The \ex{-o \var{object-file-name}} switch tells the vm where to find
relocation information for its foreign-function calls.
Scsh will use a pre-compiled default if it is not specified.
Scsh must have this information to run,
since scsh's syscall interfaces are done with foreign-function calls.
The \ex{-h} and \ex{-s} options tell the vm how much space to allocate
for the heap and stack.
\subsection{End options}
End options terminate argument parsing.
The \ex{-i} switch is followed by the name of a heap image for the
vm to execute, and terminates vm argument parsing;
following arguments are passed off to the heap image's top-level program.
The \ex{--} switch terminates argument parsing without giving
a specific heap image; the vm will start up with using a default
heap (whose location is compiled into the vm).
Notice that you are not allowed to pass arguments to the heap image's
top-level program (\eg, scsh) without delimiting them with \ex{-i}
or \ex{--} flags.
\section{Scsh arguments}
\label{sec:scsh-args}
Scsh's top-level argument parser takes arguments in a simple
format:
\codex{scsh [\var{end-option} \vari{arg}1 {\ldots} \vari{arg}n]}
where
\begin{inset}
\begin{tabular}{ll}
\var{end-option:} & \ex{-s} \var{script} \\
& \ex{--}
\end{tabular}
\end{inset}
The \ex{-s} argument causes scsh to load a script file and exit.
It also terminates argument parsing; following arguments are passed
to the scsh program as the value of \ex{command-line-arguments}.
If the \ex{-s} argument is not given, scsh runs in interactive mode,
with a standard {\scm} prompt-read-eval-print loop.
The \ex{--} switch terminates argument parsing without specifying a
script to load; it allows the user to pass arguments to an interactive scsh.
Shell scripts can be written and invoked with a \ex{\#!} initial line.
Scsh defines the sequence \ex{\#!} to be a read-macro similar
to the comment character \ex{;}.
The read-macro causes scsh to skip characters until it reads a newline,
\ex{!}, \ex{\#}, newline sequence.
So an initial \ex{\#!} line is ignored by scsh.
% Since there is no standalone scsh binary, scsh scripts must do a double
% level-shift, invoking the vm on the scsh heap image on the scsh script.
% The appropriate magic top three lines are:
% \begin{code}
% #!/usr/local/bin/scshvm \\
% -o /usr/local/bin/scshvm -i /usr/local/lib/scsh/scsh.image -s
% !#
% {\ldots} \textnormal{\emph{Your Scheme code goes here}} \ldots\end{code}
\section{Compiling shell scripts}
The {\Scheme} implementation of scsh allows you to create a heap image
with your own top-level procedure.
Adding the pair of lines
\begin{code}
#!/usr/local/bin/scshvm \\\\
-o /usr/local/bin/scshvm -i
\end{code}
to the top of the heap image will turn it into an executable {\Unix} file.
\defun{dump-scsh-program}{main fname}{\undefined}
\begin{desc}
This procedure writes out a scsh heap image. When the
heap image is executed by the {\Scheme} vm, it will call
the \var{main} procedure on no arguments and then exit.
The {\Scheme} vm will parse command-line arguments as
described in section~\ref{sec:vm-args}, and bind remaining
arguments to the \ex{command-line-arguments} variable before
calling \ex{main}. Further argument parsing (as described for
scsh in section~\ref{sec:scsh-args} is not performed.
The heap image created by \ex{dump-scsh-program} has unused
code and data pruned out, so small programs compile to much smaller
heap images.
\end{desc}
\section{Standard file locations}
Because the scshvm binary is intended to be used for writing shell
scripts, it is important that the binary be installed in a standard
place, so that shell scripts can dependably refer to it.
The standard directory for the scsh tree should be \ex{/usr/local/lib/scsh/}.
Whenever possible, the vm should be located in
\codex{/usr/local/lib/scsh/scshvm}
and a scsh heap image should be located in
\codex{/usr/local/lib/scsh/scsh.image}
The top-level scsh program should be located in
\codex{/usr/local/lib/scsh/scsh}
with a symbolic link to it from
\codex{/usr/local/bin/scsh}
The {\scm} image format allows heap images to have \ex{\#!} triggers,
so \ex{scsh.image} should have a \ex{\#!} trigger of the following form:
\begin{code}
#!/usr/local/bin/scshvm \\
-o /usr/local/bin/scshvm -i
{\ldots} \textnormal{\emph{heap image goes here}} \ldots\end{code}