Shell variables may be given values
or when a shell procedure is invoked.
An argument to a shell procedure of the form
that precedes the command name
to be assigned to \fIname\fP
before execution of the procedure begins.
The value of \fIname\fP in the invoking
will execute \fIcommand\fP with
\fBuser\fP set to \fIfred\fP.
The \fB\(mik\fR flag causes arguments of the form
\fIname=value\fP to be interpreted in this way
anywhere in the argument list.
Such \fInames\fP are sometimes
called keyword parameters.
If any arguments remain they
are available as positional
parameters \fB$1, $2, \*(ZZ\|.\fP
may also be used to set positional parameters
will set \fB$1\fP to the first file name
in the current directory, \fB$2\fP to the next,
Note that the first argument, \(mi, ensures correct treatment
when the first file name begins with a \(mi\|.
3.1\ Parameter\ transmission
When a shell procedure is invoked both positional
and keyword parameters may be supplied with the call.
Keyword parameters are also made available implicitly
by specifying in advance that such parameters
marks the variables \fBuser\fP and \fBbox\fP
When a shell procedure is invoked
copies are made of all exportable variables
for use within the invoked procedure.
Modification of such variables
within the procedure does not
affect the values in the invoking shell.
of its caller without explicit
request on the part of the caller.
(Shared file descriptors are an
Names whose value is intended to remain
constant may be declared \fIreadonly\|.\fP
The form of this command is the same as that of the \fIexport\fP
Subsequent attempts to set readonly variables
3.2\ Parameter\ substitution
If a shell parameter is not set
then the null string is substituted for it.
For example, if the variable \fBd\fP
A default string may be given
the value of the variable \fBd\fP
if it is set and `\fB.\fP' otherwise.
The default string is evaluated using the usual
quoting conventions so that
will echo \fB\*(ST\fP if the variable \fBd\fP
will echo the value of \fBd\fP if it is set
and the value (if any) of \fB$1\fP otherwise.
A variable may be assigned a default value
which substitutes the same string as
and if \fBd\fP were not previously set
then it will be set to the string `\fB.\fP'\|.
(The notation ${\*(ZZ=\*(ZZ}
is not available for positional parameters.)
If there is no sensible default then
will echo the value of the variable \fBd\fP if it has
one, otherwise \fImessage\fP is printed by the shell and
execution of the shell procedure is abandoned.
If \fImessage\fP is absent then a standard message
A shell procedure that requires some parameters
to be set might start as follows.
:\ ${user?}\ ${acct?}\ ${bin?}
Colon (\fB:\fP) is a command
built in to the shell and does nothing
once its arguments have been evaluated.
If any of the variables \fBuser, acct\fP
or \fBbin\fP are not set then the shell
will abandon execution of the procedure.
3.3\ Command\ substitution
The standard output from a command can be
substituted in a similar way to parameters.
The command \fIpwd\fP prints on its standard
output the name of the current directory.
For example, if the current directory is
The entire string between grave accents (\`\*(ZZ\`)
and is replaced with the output from
The command is written using the usual
except that a \fB\`\fR must be escaped using
Command substitution occurs in all contexts
where parameter substitution occurs (including \fIhere\fP documents) and the
treatment of the resulting text is the same
This mechanism allows string
processing commands to be used within
An example of such a command is \fIbasename\fP
which removes a specified suffix from a string.
basename main\fB.\fPc \fB.\fPc
will print the string \fImain\|.\fP
Its use is illustrated by the following
fragment from a \fIcc\fP command.
\*(Ca\*(ST\fB.\fPc) B=\`basename $A \fB.\fPc\`
that sets \fBB\fP to the part of \fB$A\fP
with the suffix \fB.c\fP stripped.
Here are some composite examples.
for i in \`ls \(mit\`; do \*(ZZ
The variable \fBi\fP is set
to the names of files in time order,
set \`date\`; echo $6 $2 $3, $4
3.4\ Evaluation\ and\ quoting
The shell is a macro processor that
provides parameter substitution, command substitution and file
name generation for the arguments to commands.
This section discusses the order in which
these evaluations occur and the
effects of the various quoting mechanisms.
Commands are parsed initially according to the grammar
Before a command is executed
parameter substitution, e.g. \fB$user\fP
command substitution, e.g. \fB\`pwd\`\fP
Only one evaluation occurs so that if, for example, the value of the variable
Following the above substitutions
are broken into non-blank words (\fIblank interpretation\fP).
For this purpose `blanks' are the characters of the string
By default, this string consists of blank, tab and newline.
is not regarded as a word unless it is quoted.
will pass on the null string as the first argument to \fIecho\fP,
will call \fIecho\fR with no arguments
if the variable \fBnull\fP is not set
or set to the null string.
is then scanned for the file pattern characters
\fB\*(ST, ?\fR and \fB[\*(ZZ]\fR
and an alphabetical list of file names
is generated to replace the word.
Each such file name is a separate argument.
The evaluations just described also occur
in the list of words associated with a \fBfor\fP
As well as the quoting mechanisms described
earlier using \fB\\\fR and \fB\'\*(ZZ\'\fR
a third quoting mechanism is provided using double quotes.
Within double quotes parameter and command substitution
occurs but file name generation and the interpretation
have a special meaning within double quotes
and may be quoted using \fB\\\|.\fP
\fB$ \fPparameter substitution
\fB\`\fP command substitution
\fB"\fP ends the quoted string
\fB\e\fP quotes the special characters \fB$ \` " \e\fP
will pass the value of the variable \fBx\fP as a
single argument to \fIecho.\fP
will pass the positional parameters as a single
argument and is equivalent to
is the same as \fB$\*(ST\fR
except when it is quoted.
will pass the positional parameters, unevaluated, to \fIecho\fR
The following table gives, for each quoting mechanism,
the shell metacharacters that are evaluated.
Figure 2. Quoting mechanisms
In cases where more than one evaluation of a string
is required the built-in command \fIeval\fP
if the variable \fBX\fP has the value
\fI$y\fP, and if \fBy\fP has the value \fIpqr\fP
will echo the string \fIpqr\|.\fP
In general the \fIeval\fP command
evaluates its arguments (as do all commands)
and treats the result as input to the shell.
The input is read and the resulting command(s)
wg=\\'eval who\*(VTgrep\\'
since there is no interpretation
of metacharacters, such as \fB\*(VT\|,\fP following
The treatment of errors detected by
the shell depends on the type of error
and on whether the shell is being
An interactive shell is one whose
input and output are connected
to a terminal (as determined by
A shell invoked with the \fB\(mii\fP
flag is also interactive.
Execution of a command (see also 3.7) may fail
for any of the following reasons.
Input output redirection may fail.
For example, if a file does not exist
The command itself does not exist
The command terminates abnormally,
for example, with a "bus error"
See Figure 2 below for a complete list
The command terminates normally
but returns a non-zero exit status.
In all of these cases the shell
will go on to execute the next command.
Except for the last case an error
message will be printed by the shell.
All remaining errors cause the shell
to exit from a command procedure.
An interactive shell will return
to read another command from the terminal.
Such errors include the following.
e.g., if \*(ZZ then \*(ZZ done
A signal such as interrupt.
The shell waits for the current
command, if any, to finish execution and
then either exits or returns to the terminal.
Failure of any of the built-in commands
The shell flag \fB\(mie\fP
causes the shell to terminate
if any error is detected.
8* floating point exception
9 kill (cannot be caught or ignored)
11* segmentation violation
12* bad argument to system call
13 write on a pipe with no one to read it
15 software termination (from \fIkill\fP (1))
Those signals marked with an asterisk
the shell itself ignores quit which is the only
external signal that can cause a dump.
The signals in this list of potential interest
to shell programs are 1, 2, 3, 14 and 15.
Shell procedures normally terminate
when an interrupt is received from the
The \fItrap\fP command is used
if some cleaning up is required, such
as removing temporary files.
trap\ \'rm\ /tmp/ps$$; exit\'\ 2
sets a trap for signal 2 (terminal
interrupt), and if this signal is received
will execute the commands
that terminates execution of a shell procedure.
The \fIexit\fP is required; otherwise,
after the trap has been taken,
the shell will resume executing
at the place where it was interrupted.
UNIX signals can be handled in one of three ways.
They can be ignored, in which case
the signal is never sent to the process.
They can be caught, in which case the process
must decide what action to take when the
Lastly, they can be left to cause
termination of the process without
it having to take any further action.
If a signal is being ignored
on entry to the shell procedure, for example,
by invoking it in the background (see 3.7) then \fItrap\fP
commands (and the signal) are ignored.
The use of \fItrap\fP is illustrated
by this modified version of the \fItouch\fP
The cleanup action is to remove the file \fBjunk$$\fR\|.
trap\ \'rm\ \(mif\ junk$$;\ exit\'\ 1 2 3 15
\*(DC\*(ST) if\ test\ \(mif\ $i
\*(DC then ln\ $i\ junk$$;\ rm\ junk$$
\*(DC then echo\ file\ \\\\\'$i\\\\\'\ does\ not\ exist
Figure 4. The touch command
appears before the creation
Since there is no signal 0 in UNIX
it is used by the shell to indicate the
commands to be executed on exit from the
A procedure may, itself, elect to
ignore signals by specifying the null
string as the argument to trap.
The following fragment is taken from the
which causes \fIhangup, interrupt, quit \fRand\fI kill\fR
to be ignored both by the
procedure and by invoked commands.
Traps may be reset by saying
which resets the traps for signals 2 and 3 to their default values.
A list of the current values of traps may be obtained
The procedure \fIscan\fP (Figure 5) is an example
of the use of \fItrap\fP where there is no exit
\fIscan\fP takes each directory
in the current directory, prompts
with its name, and then executes
commands typed at the terminal
until an end of file or an interrupt is received.
Interrupts are ignored while executing
the requested commands but cause
termination when \fIscan\fP is
do\ if\ test\ \(mid\ $d/$i
\*(DO\*(THwhile\ echo\ "$i:"
\*(DO\*(TH\*(WHtrap\ exit\ 2
\*(DO\*(THdo\ trap\ :\ 2;\ eval\ $x;\ done
Figure 5. The scan command
\fIread x\fR is a built-in command that reads one line from the
and places the result in the variable \fBx\|.\fP
It returns a non-zero exit status if either
an end-of-file is read or an interrupt
To run a command (other than a built-in) the shell first creates
a new process using the system call \fIfork.\fP
The execution environment for the command
includes input, output and the states of signals, and
is established in the child process
before the command is executed.
The built-in command \fIexec\fP
is used in the rare cases when no fork
and simply replaces the shell with a new command.
For example, a simple version of the \fInohup\fP
The \fItrap\fP turns off the signals specified
so that they are ignored by subsequently created commands
and \fIexec\fP replaces the shell by the command
Most forms of input output redirection have already been
In the following \fIword\fP is only subject
to parameter and command substitution.
No file name generation or blank interpretation
takes place so that, for example,
will write its output into a file whose name is \fB\*(ST.c\|.\fP
Input output specifications are evaluated left to right
as they appear in the command.
The standard output (file descriptor 1)
is sent to the file \fIword\fP which is
created if it does not already exist.
The standard output is sent to file \fIword.\fP
If the file exists then output is appended
otherwise the file is created.
The standard input (file descriptor 0)
is taken from the file \fIword.\fP
The standard input is taken from the lines
of shell input that follow up to but not
including a line consisting only of \fIword.\fP
If \fIword\fP is quoted then no interpretation
If \fIword\fP is not quoted
then parameter and command substitution
occur and \fB\\\fP is used to quote
the characters \fB\\\fP \fB$\fP \fB\`\fP and the first character
In the latter case \fB\\newline\fP is ignored (c.f. quoted strings).
The file descriptor \fIdigit\fP is duplicated using the system
and the result is used as the standard output.
The standard input is duplicated from file descriptor \fIdigit.\fP
The standard input is closed.
The standard output is closed.
Any of the above may be preceded by a digit in which
case the file descriptor created is that specified by the digit
instead of the default 0 or 1.
runs a command with message output (file descriptor 2)
runs a command with its standard output and message output
(Strictly speaking file descriptor 2 is created
by duplicating file descriptor 1 but the effect is usually to
The environment for a command run in the background such as
Firstly, the default standard input
for such a command is the empty file \fB/dev/null\|.\fR
This prevents two processes (the shell and the command),
which are running in parallel, from trying to
if this were not the case.
would allow both the editor and the shell
to read from the same input at the same time.
The other modification to the environment of a background
command is to turn off the QUIT and INTERRUPT signals
so that they are ignored by the command.
This allows these signals to be used
at the terminal without causing background
For this reason the UNIX convention
for a signal is that if it is set to 1
(ignored) then it is never changed
Note that the shell command \fItrap\fP
has no effect for an ignored signal.
3.8\ Invoking\ the\ shell
The following flags are interpreted by the shell
If the first character of argument zero is a minus,
then commands are read from the file \fB.profile\|.\fP
.IP \fB\(mic\fP\ \fIstring\fP
If the \fB\(mic\fP flag is present then
commands are read from \fIstring\|.\fP
If the \fB\(mis\fP flag is present or if no
then commands are read from the standard input.
Shell output is written to
If the \fB\(mii\fP flag is present or
if the shell input and output are attached to a terminal (as told by \fIgtty\fP)
then this shell is \fIinteractive.\fP
In this case TERMINATE is ignored (so that \fBkill 0\fP
does not kill an interactive shell) and INTERRUPT is caught and ignored
(so that \fBwait\fP is interruptable).
In all cases QUIT is ignored by the shell.
The design of the shell is
based in part on the original UNIX shell
unix command language thompson
features having been taken from both.
Similarities also exist with the
of the Cambridge Multiple Access System
cambridge multiple access system hartley
I would like to thank Dennis Ritchie
discussions during the design of the shell.
I am also grateful to the members of the Computing Science Research Center
and to Joe Maranzano for their
comments on drafts of this document.