SysIII/usr/src/man/docs/shell

.ds :? Shell
.de PT
.lt \\n(LLu
.pc %
.nr PN \\n%
.if \\n%-1 .if o .tl '\s9\f2\*(:?\fP''\\n(PN\s0'
.if \\n%-1 .if e .tl '\s9\\n(PN''\f2\*(:?\^\fP\s0'
.lt \\n(.lu
..
.hy 14
.ds ZZ \fB.\|.\|.\fP
.ds ST \v'.3m'\s+2*\s0\v'-.3m'
.ds DO \h'\w'do 'u'
.ds Ca \h'\w'case 'u'
.ds WH \h'\w'while 'u'
.ds VT \|\fB\(or\fP\|
.ds TH \h'\w'then 'u'
.ds DC \*(DO\*(CA
.ds AP >\h'-.2m'>
.ds HE <\h'-.2m'<
..	\" macros for algol 68c reference manual
.ds DA 1977 November 1
.ds md \v'.25m'
.ds mu \v'-.25m'
.ds U \*(mu\s-3
.ds V \s0\*(md
.ds L \*(md\s-3
.ds M \s0\*(mu
.ds S \s-1
.ds T \s0
..	\" small 1
.ds O \*S1\*T
.ds h \|
.ds s \|\|
..	\" ellipsis
.ds e .\|.\|.
..	\" subscripts
.ds 1 \*(md\s-41\s0\*(mu
.ds 2 \*(md\s-42\s0\*(mu
'\"	.RP
.TL 
An Introduction to the U\s-2NIX\s+2 Shell
.AU
S. R. Bourne
.AI
.MH
.AB
.LP
The
.ul
shell
is a command programming language that provides an interface
to the
.UX
operating system.
Its features include
control-flow primitives, parameter passing, variables and
string substitution.
Constructs such as
.ul
while, if then else, case
and
.ul
for
are available.
Two-way communication is possible between the
.ul
shell
and commands.
String-valued parameters, typically file names or flags, may be
passed to a command.
A return code is set by commands that may be used to determine control-flow,
and the standard output from a command may be used
as shell input.
.LP
The
.ul
shell
can modify the environment
in which commands run.
Input and output can be redirected
to files, and processes that communicate through `pipes'
can be invoked.
Commands are found by
searching directories
in the file system in a
sequence that can be defined by the user.
Commands can be read either from the terminal or from a file,
which allows command procedures to be
stored for later use.
.AE
.ds ST \v'.3m'\s+2*\s0\v'-.3m'
.SH
1.0\ Introduction
.LP
The shell is both a command language
and a programming language
that provides an interface to the UNIX
operating system.
This memorandum describes, with
examples, the UNIX shell.
The first section covers most of the
everyday requirements
of terminal users.
Some familiarity with UNIX
is an advantage when reading this section;
see, for example,
\f2UNIX for Beginners\fP\*(<.\*([.1\*(.]\*(>.
Section 2 describes those features
of the shell primarily intended
for use within shell procedures.
These include the control-flow
primitives and string-valued variables
provided by the shell.
A knowledge of a programming language
would be a help when reading this section.
The last section describes the more
advanced features of the shell.
References of the form ``see \fIpipe\fP (2)''
are to a section of the UNIX manual\*(<.\*([.2\*(.]\*(>.
.SH
1.1\ Simple\ commands
.LP
Simple commands consist of one or more words
separated by blanks.
The first word is the name of the command
to be executed; any remaining words
are passed as arguments to the command.
For example,
.DS
	who
.DE
is a command that prints the names
of users logged in.
The command
.DS
	ls \(mil
.DE
prints a list of files in the current
directory.
The argument \fI\(mil\fP tells \fIls\fP
to print status information, size and
the creation date for each file.
.SH
1.2\ Background\ commands
.LP
To execute a command the shell normally
creates a new \fIprocess\fP
and waits for it to finish.
A command may be run without waiting
for it to finish.
For example,
.DS
	cc pgm.c &
.DE
calls the C compiler to compile
the file \fIpgm.c\|.\fP
The trailing \fB&\fP is an operator that instructs the shell
not to wait for the command to finish.
To help keep track of such a process
the shell reports its process
number following its creation.
A list of currently active processes may be obtained
using the \fIps\fP command.
.SH
1.3\ Input\ output\ redirection
.LP
Most commands produce output on the standard output
that is initially connected to the terminal.
This output may be sent to a file
by writing, for example,
.DS
	ls \(mil >file
.DE
The notation \fI>file\fP
is interpreted by the shell and is not passed
as an argument to \fIls.\fP
If \fIfile\fP does not exist then the
shell creates it;
otherwise the original contents of
\fIfile\fP are replaced with the output
from \fIls.\fP
Output may be appended to a file
using the notation
.DS
	ls \(mil \*(APfile
.DE
In this case \fIfile\fP is also created if it does not already
exist.
.LP
The standard input of a command may be taken
from a file instead of the terminal by
writing, for example,
.DS
	wc <file
.DE
The command \fIwc\fP reads its standard input
(in this case redirected from \fIfile\fP)
and prints the number of characters, words and
lines found.
If only the number of lines is required
then
.DS
	wc \(mil <file
.DE
could be used.
.SH
1.4\ Pipelines\ and\ filters
.LP
The standard output of one command may be
connected to the standard input of another
by writing
the `pipe' operator,
indicated by \*(VT,
as in,
.DS
	ls \(mil \*(VT wc
.DE
Two commands connected in this way constitute
a \fIpipeline\fP and
the overall effect is the same as
.DS
	ls \(mil >file; wc <file
.DE
except that no \fIfile\fP is used.
Instead the two processes are connected
by a pipe (see \fIpipe\fP (2)) and are
run in parallel.
Pipes are unidirectional and
synchronization is achieved by
halting \fIwc\fP when there is
nothing to read and halting \fIls\fP
when the pipe is full.
.LP
A \fIfilter\fP is a command
that reads its standard input,
transforms it in some way,
and prints the result as output.
One such filter, \fIgrep,\fP
selects from its input those lines
that contain some specified string.
For example,
.DS
	ls \*(VT grep old
.DE
prints those lines, if any, of the output
from \fIls\fP that contain
the string \fIold.\fP
Another useful filter is \fIsort\fP.
For example,
.DS
	who \*(VT sort
.DE
will print an alphabetically sorted list
of logged in users.
.LP
A pipeline may consist of more than two commands,
for example,
.DS
	ls \*(VT grep old \*(VT wc \(mil
.DE
prints the number of file names
in the current directory containing
the string \fIold.\fP
.SH
1.5\ File\ name\ generation
.LP
Many commands accept arguments
which are file names.
For example,
.DS
	ls \(mil main.c
.DE
prints information relating to the file \fImain.c\fP\|.
.LP
The shell provides a mechanism
for generating a list of file names
that match a pattern.
For example,
.DS
	ls \(mil \*(ST.c
.DE
generates, as arguments to \fIls,\fP
all file names in the current directory that end in \fI.c\|.\fP
The character \*(ST is a pattern that will match any string
including the null string.
In general \fIpatterns\fP are specified
as follows.
.RS
.IP \fB\*(ST\fR 8
Matches any string of characters
including the null string.
.IP \fB?\fR 8
Matches any single character.
.IP \fB[\*(ZZ]\fR 8
Matches any one of the characters
enclosed.
A pair of characters separated by a minus will
match any character lexically between
the pair.
.RE
.LP
For example,
.DS
	[a\(miz]\*(ST
.DE
matches all names in the current directory
beginning with
one of the letters \fIa\fP through \fIz.\fP
.DS
	/usr/fred/test/?
.DE
matches all names in the directory
\fB/usr/fred/test\fP that consist of a single character.
If no file name is found that matches
the pattern then the pattern is passed,
unchanged, as an argument.
.LP
This mechanism is useful both to save typing
and to select names according to some pattern.
It may also be used to find files.
For example,
.DS
	echo /usr/fred/\*(ST/core
.DE
finds and prints the names of all \fIcore\fP files in sub-directories
of \fB/usr/fred\|.\fP
(\fIecho\fP is a standard UNIX command that prints
its arguments, separated by blanks.)
This last feature can be expensive,
requiring a scan of all
sub-directories of \fB/usr/fred\|.\fP
.LP
There is one exception to the general
rules given for patterns.
The character `\fB.\fP'
at the start of a file name must be explicitly
matched.
.DS
	echo \*(ST
.DE
will therefore echo all file names in the current
directory not beginning
with `\fB.\fP'\|.
.DS
	echo \fB.\fP\*(ST
.DE
will echo all those file names that begin with `\fB.\fP'\|.
This avoids inadvertent matching
of the names `\fB.\fP' and `\fB..\fP'
which mean `the current directory'
and `the parent directory'
respectively.
(Notice that \fIls\fP suppresses
information for the files `\fB.\fP' and `\fB..\fP'\|.)
.SH
1.6\ Quoting
.LP
Characters that have a special meaning
to the shell, such as \fB< > \*(ST ? \*(VT &\|,\fR
are called metacharacters.
A complete list of metacharacters is given
in appendix B.
Any character preceded by a \fB\\\fR is \fIquoted\fP
and loses its special meaning, if any.
The \fB\\\fP is elided so that
.DS
	echo \\\\?
.DE
will echo a single \fB?\|,\fP
and
.DS
	echo \\\\\\\\
.DE
will echo a single \fB\\\|.\fR
To allow long strings to be continued over
more than one line
the sequence \fB\\newline\fP
is ignored.
The
\fB\\\fP is convenient for quoting
single characters.
When more than one character needs
quoting the above mechanism is clumsy and
error prone.
A string of characters may be quoted
by enclosing the string between single quotes.
For example,
.DS
	echo xx\'\*(ST\*(ST\*(ST\*(ST\'xx
.DE
will echo
.DS
	xx\*(ST\*(ST\*(ST\*(STxx
.DE
The quoted string may not contain
a single quote
but may contain newlines, which are preserved.
This quoting mechanism is the most
simple and is recommended
for casual use.
A third quoting mechanism using double quotes
is also available
that prevents interpretation of some but not all
metacharacters.
Discussion of the
details is deferred
to section 3.4\|.
.SH
1.7\ Prompting
.LP
When the shell is used from a terminal it will
issue a prompt before reading a command.
By default this prompt is `\fB$\ \fR'\|.
It may be changed by saying,
for example,
.DS
	\s-1PS1\s0=yesdear
.DE
that sets the prompt to be the string \fIyesdear\|.\fP
If a newline is typed and further input is needed
then the shell will issue the prompt `\fB>\ \fR'\|.
Sometimes this can be caused by mistyping
a quote mark.
If it is unexpected then an interrupt (\s-1DEL\s0)
will return the shell to read another command.
This prompt may be changed by saying, for example,
.DS
	\s-1PS2\s0=more
.DE
.sp -.5v
.SH
1.8\ The\ shell\ and\ login
.LP
Following \fIlogin\fP (1)
the shell is called to read and execute
commands typed at the terminal.
If the user's login directory
contains the file \fB.profile\fP
then it is assumed to contain commands
and is read by the shell before reading
any commands from the terminal.
.SH
1.9\ Summary
.RS
.IP \(bu
\fBls\fP
.br
Print the names of files in the current directory.
.IP \(bu
\fBls >file\fP
.br
Put the output from \fIls\fP into \fIfile.\fP
.IP \(bu
\fBls \*(VT wc \(mil\fR
.br
Print the number of files in the current directory.
.IP \(bu
\fBls \*(VT grep old\fR
.br
Print those file names containing the string \fIold.\fP
.IP \(bu
\fBls \*(VT grep old \*(VT wc \(mil\fR
.br
Print the number of files whose name contains the string \fIold.\fP
.IP \(bu
\fBcc pgm.c &\fR
.br
Run \fIcc\fP in the background.
.RE
.SH
2.0\ Shell\ procedures
.LP
The shell may be used to read and execute commands
contained in a file.
For example,
.DS
	sh file [ args \*(ZZ ]
.DE
calls the shell to read commands from \fIfile.\fP
Such a file is called a \fIcommand procedure\fP
or \fIshell procedure.\fP
Arguments may be supplied with the call
and are referred to in \fIfile\fP
using the positional parameters
\fB$1, $2, \*(ZZ\|.\fR
For example, if the file \fIwg\fP contains
.DS
	who \*(VT grep $1
.DE
then
.DS
	sh wg fred
.DE
is equivalent to
.DS
	who \*(VT grep fred
.DE
.LP
UNIX files have three independent attributes,
\fIread,\fP \fIwrite\fP and \fIexecute.\fP
The UNIX command \fIchmod\fP (1) may be used
to make a file executable.
For example,
.DS
	chmod +x wg
.DE
will ensure that the file \fIwg\fP has execute status.
Following this, the command
.DS
	wg fred
.DE
is equivalent to
.DS
	sh wg fred
.DE
This allows shell procedures and programs
to be used interchangeably.
In either case a new process is created to
run the command.
.LP
As well as providing names for the positional
parameters,
the number of positional parameters in the call
is available as \fB$#\|.\fP
The name of the file being executed
is available as \fB$0\|.\fP
.LP
A special shell parameter \fB$\*(ST\fP
is used to substitute for all positional parameters
except \fB$0\|.\fP
A typical use of this is to provide
some default arguments,
as in,
.DS
	nroff \(miT450 \(micm $\*(ST
.DE
which simply prepends some arguments
to those already given.
.SH
2.1\ Control\ flow\ -\ for
.LP
A frequent use of shell procedures is to loop
through the arguments (\fB$1, $2, \*(ZZ\fR)
executing commands once for each argument.
An example of such a procedure is
\fItel\fP that searches the file
\fB/usr/lib/telnos\fR
that contains lines of the form
.DS
	\*(ZZ
	fred mh0123
	bert mh0789
	\*(ZZ
.DE
The text of \fItel\fP is
.DS
	for i
	do grep $i /usr/lib/telnos; done
.DE
The command
.DS
	tel fred
.DE
prints those lines in \fB/usr/lib/telnos\fR
that contain the string \fIfred\|.\fP
.DS
	tel fred bert
.DE
prints those lines containing \fIfred\fP
followed by those for \fIbert.\fP
.LP
The \fBfor\fP loop notation is recognized by the shell
and has the general form
.DS
	\fBfor\fR \fIname\fR \fBin\fR \fIw1 w2 \*(ZZ\fR
	\fBdo\fR \fIcommand-list\fR
	\fBdone\fR
.DE
A \fIcommand-list\fP is a sequence of one or more
simple commands separated or terminated by a newline or semicolon.
Furthermore, reserved words
like \fBdo\fP and \fBdone\fP are only
recognized following a newline or
semicolon.
\fIname\fP is a shell variable that is set
to the words \fIw1 w2 \*(ZZ\fR in turn each time the \fIcommand-list\fP
following \fBdo\fP
is executed.
If \fBin\fR \fIw1 w2 \*(ZZ\fR
is omitted then the loop
is executed once for each positional parameter;
that is, \fBin\fR \fI$\*(ST\fR is assumed.
.LP
Another example of the use of the \fBfor\fP
loop is the \fIcreate\fP command
whose text is
.DS
	for i do >$i; done
.DE
The command
.DS
	create alpha beta
.DE
ensures that two empty files
\fIalpha\fP and \fIbeta\fP exist
and are empty.
The notation \fI>file\fP may be used on its
own to create or clear the contents of a file.
Notice also that a semicolon (or newline) is required before \fBdone.\fP
.SH
2.2\ Control\ flow\ -\ case
.LP
A multiple way branch is provided for by the
\fBcase\fP notation.
For example,
.DS
	case $# in
	\*(Ca1)	cat \*(AP$1 ;;
	\*(Ca2)	cat \*(AP$2 <$1 ;;
	\*(Ca\*(ST)	echo \\'usage: append [ from ] to\\' ;;
	esac
.DE
is an \fIappend\fP command.
When called
with one argument as
.DS
	append file
.DE
\fB$#\fP is the string \fI1\fP and
the standard input is copied onto the
end of \fIfile\fP
using the \fIcat\fP command.
.DS
	append file1 file2
.DE
appends the contents of \fIfile1\fP
onto \fIfile2.\fP
If the number of arguments supplied to
\fIappend\fP is other than 1 or 2
then a message is printed indicating
proper usage.
.LP
The general form of the \fBcase\fP command
is
.DS
	\fBcase \fIword \fBin
	\*(Ca\fIpattern\|\fB)\ \fIcommand-list\fB\|;;
	\*(Ca\*(ZZ
	\fBesac\fR
.DE
The shell attempts to match
\fIword\fR with each \fIpattern,\fR
in the order in which the patterns
appear.
If a match is found the
associated \fIcommand-list\fP is
executed and execution
of the \fBcase\fP is complete.
Since \*(ST is the pattern that matches any
string it can be used for the default case.
.LP
A word of caution:
no check is made to ensure that only
one pattern matches
the case argument.
The first match found defines the set of commands
to be executed.
In the example below the commands following
the second \*(ST will never be executed.
.DS
	case $# in
	\*(Ca\*(ST) \*(ZZ ;;
	\*(Ca\*(ST) \*(ZZ ;;
	esac
.DE
.LP
Another example of the use of the \fBcase\fP
construction is to distinguish
between different forms
of an argument.
The following example is a fragment of a \fIcc\fP command.
.DS
	for i
	do case $i in
	\*(DC\(mi[ocs])	\*(ZZ ;;
	\*(DC\(mi\*(ST)	echo \\'unknown flag $i\\' ;;
	\*(DC\*(ST.c)	/lib/c0 $i \*(ZZ ;;
	\*(DC\*(ST)	echo \\'unexpected argument $i\\' ;;
	\*(DOesac
	done
.DE
.LP
To allow the same commands to be associated
with more than one pattern
the \fBcase\fP command provides
for alternative patterns
separated by a \*(VT\|.
For example,
.DS
	case $i in
	\*(Ca\(mix\*(VT\(miy)	\*(ZZ
	esac
.DE
is equivalent to
.DS
	case $i in
	\*(Ca\(mi[xy])	\*(ZZ
	esac
.DE
.LP
The usual quoting conventions apply
so that
.DS
	case $i in
	\*(Ca\\\\?)	\*(ZZ
.DE
will match the character \fB?\|.\fP
.SH
2.3\ Here\ documents
.LP
The shell procedure \fItel\fP
in section 2.1 uses the file \fB/usr/lib/telnos\fR
to supply the data
for \fIgrep.\fP
An alternative is to include this
data
within the shell procedure as a \fIhere\fP document, as in,
.DS
	for i
	do grep $i \*(HE!
	\*(DO\*(ZZ
	\*(DOfred mh0123
	\*(DObert mh0789
	\*(DO\*(ZZ
	!
	done
.DE
In this example
the shell takes the lines between \fB\*(HE!\fR and \fB!\fR
as the standard input for \fIgrep.\fP
The string \fB!\fR is arbitrary, the document
being terminated by a line that consists
of the string following \*(HE\|.
.LP
Parameters are substituted in the document
before it is made available to \fIgrep\fP
as illustrated by the following procedure
called \fIedg\|.\fP
.DS
	ed $3 \*(HE%
	g/$1/s//$2/g
	w
	%
.DE
The call
.DS
	edg string1 string2 file
.DE
is then equivalent to the command
.DS
	ed file \*(HE%
	g/string1/s//string2/g
	w
	%
.DE
and changes all occurrences of \fIstring1\fP
in \fIfile\fP to \fIstring2\|.\fP
Substitution can be prevented using \\
to quote the special character \fB$\fP
as in
.DS
	ed $3 \*(HE+
	1,\\\\$s/$1/$2/g
	w
	+
.DE
(This version of \fIedg\fP is equivalent to
the first except that \fIed\fP will print
a \fB?\fR if there are no occurrences of
the string \fB$1\|.\fP)
Substitution within a \fIhere\fP document
may be prevented entirely by quoting
the terminating string,
for example,
.DS
	grep $i \*(HE\\\\#
	\*(ZZ
	#
.DE
The document is presented
without modification to \fIgrep.\fP
If parameter substitution is not required
in a \fIhere\fP document this latter form
is more efficient.
.SH
2.4\ Shell\ variables
.LP
The shell
provides string-valued variables.
Variable names begin with a letter
and consist of letters, digits and
underscores.
Variables may be given values by writing, for example,
.DS
	user=fred\ box=m000\ acct=mh0000
.DE
which assigns values to the variables
\fBuser, box\fP and \fBacct.\fP
A variable may be set to the null string
by saying, for example,
.DS
	null=
.DE
The value of a variable is substituted
by preceding its name with \fB$\|;\fP
for example,
.DS
	echo $user
.DE
will echo \fIfred.\fP
.LP
Variables may be used interactively
to provide abbreviations for frequently
used strings.
For example,
.DS
	b=/usr/fred/bin
	mv pgm $b
.DE
will move the file \fIpgm\fP
from the current directory to the directory \fB/usr/fred/bin\|.\fR
A more general notation is available for parameter
(or variable)
substitution, as in,
.DS
	echo ${user}
.DE
which is equivalent to
.DS
	echo $user
.DE
and is used when the parameter name is
followed by a letter or digit.
For example,
.DS
	tmp=/tmp/ps
	ps a >${tmp}a
.DE
will direct the output of \fIps\fR
to the file \fB/tmp/psa,\fR
whereas,
.DS
	ps a >$tmpa
.DE
would cause the value of the variable \fBtmpa\fP
to be substituted.
.LP
Except for \fB$?\fP the following
are set initially by the shell.
\fB$?\fP is set after executing each command.
.RS
.IP \fB$?\fP 8
The exit status (return code)
of the last command executed
as a decimal string.
Most commands return a zero exit status
if they complete successfully,
otherwise a non-zero exit status is returned.
Testing the value of return codes is dealt with
later under \fBif\fP and \fBwhile\fP commands.
.IP \fB$#\fP 8
The number of positional parameters
(in decimal).
Used, for example, in the \fIappend\fP command
to check the number of parameters.
.IP \fB$$\fP 8
The process number of this shell (in decimal).
Since process numbers are unique among
all existing processes, this string is
frequently used to generate
unique
temporary file names.
For example,
.DS
	ps a >/tmp/ps$$
	\*(ZZ
	rm /tmp/ps$$
.DE
.IP \fB$\|!\fP 8
The process number of the last process
run in the background (in decimal).
.IP \fB$\(mi\fP 8
The current shell flags, such as
\fB\(mix\fR and \fB\(miv\|.\fR
.RE
.LP
Some variables have a special meaning to the
shell and should be avoided for general
use.
.RS
.IP \fB$\s-1MAIL\s0\fP 8
When used interactively
the shell looks at the file
specified by this variable
before it issues a prompt.
If the specified file has been modified
since it
was last looked at the shell
prints the message
\fIyou have mail\fP before prompting
for the next command.
This variable is typically set
in the file \fB.profile,\fP
in the user's login directory.
For example,
.DS
	\s-1MAIL\s0=/usr/mail/fred
.DE
.IP \fB$\s-1HOME\s0\fP 8
The default argument
for the \fIcd\fP command.
The current directory is used to resolve
file name references that do not begin with
a \fB/\|,\fR
and is changed using the \fIcd\fP command.
For example,
.DS
	cd /usr/fred/bin
.DE
makes the current directory \fB/usr/fred/bin\|.\fR
.DS
	cat wn
.DE
will print on the terminal the file \fIwn\fP
in this directory.
The command
\fIcd\fP with no argument
is equivalent to
.DS
	cd $\s-1HOME\s0
.DE
This variable is also typically set in the
the user's login profile.
.IP \fB$\s-1PATH\s0\fP 8
A list of directories that contain commands (the \fIsearch path\fR\|).
Each time a command is executed by the shell
a list of directories is searched
for an executable file.
.ne 5
If \fB$\s-1PATH\s0\fP is not set
then the current directory,
\fB/bin\fP, and \fB/usr/bin\fP are searched by default.
.ne 5
Otherwise \fB$\s-1PATH\s0\fP consists of directory
names separated by \fB:\|.\fP
For example,
.DS
	\s-1PATH\s0=\fB:\fP/usr/fred/bin\fB:\fP/bin\fB:\fP/usr/bin
.DE
specifies that the current directory
(the null string before the first \fB:\fP\|),
\fB/usr/fred/bin, /bin \fRand\fP /usr/bin\fR
are to be searched in that order.
In this way individual users
can have their own `private' commands
that are accessible independently
of the current directory.
If the command name contains a \fB/\fR then this directory search
is not used; a single attempt
is made to execute the command.
.IP \fB$\s-1PS1\s0\fP 8
The primary shell prompt string, by default, `\fB$\ \fR'.
.IP \fB$\s-1PS2\s0\fP 8
The shell prompt when further input is needed,
by default, `\fB>\ \fR'.
.IP \fB$\s-1IFS\s0\fP 8
The set of characters used by \fIblank
interpretation\fR (see section 3.4).
.RE
.SH
2.5\ The\ test\ command
.LP
The \fItest\fP command, although not part of the shell,
is intended for use by shell programs.
For example,
.DS
	test \(mif file
.DE
returns zero exit status if \fIfile\fP
exists and non-zero exit status otherwise.
In general \fItest\fP evaluates a predicate
and returns the result as its exit status.
Some of the more frequently used \fItest\fP
arguments are given here, see \fItest\fP (1)
for a complete specification.
.DS
	test s		true if the argument \fIs\fP is not the null string
	test \(mif file	true if \fIfile\fP exists
	test \(mir file	true if \fIfile\fP is readable
	test \(miw file	true if \fIfile\fP is writable
	test \(mid file	true if \fIfile\fP is a directory
.DE
.SH
2.6\ Control\ flow\ -\ while
.LP
The actions of
the \fBfor\fP loop and the \fBcase\fP
branch are determined by data available to the shell.
A \fBwhile\fP or \fBuntil\fP loop
and an \fBif then else\fP branch
are also provided whose
actions are determined by the exit status
returned by commands.
A \fBwhile\fP loop has the general form
.DS
	\fBwhile\fP \fIcommand-list\*1\fP
	\fBdo\fP \fIcommand-list\*2\fP
	\fBdone\fP
.DE
.LP
The value tested by the \fBwhile\fP command
is the exit status of the last simple command
following \fBwhile.\fP
Each time round the loop
\fIcommand-list\*1\fP is executed;
if a zero exit status is returned then
\fIcommand-list\*2\fP
is executed;
otherwise, the loop terminates.
For example,
.DS
	while test $1
	do \*(ZZ
	\*(DOshift
	done
.DE
is equivalent to
.DS
	for i
	do \*(ZZ
	done
.DE
\fIshift\fP is a shell command that
renames the positional parameters
\fB$2, $3, \*(ZZ\fR as \fB$1, $2, \*(ZZ\fR
and loses \fB$1\|.\fP
.LP
Another kind of use for the \fBwhile/until\fP
loop is to wait until some
external event occurs and then run
some commands.
In an \fBuntil\fP loop
the termination condition is reversed.
For example,
.DS
	until test \(mif file
	do sleep 300; done
	\fIcommands\fP
.DE
will loop until \fIfile\fP exists.
Each time round the loop it waits for
5 minutes before trying again.
(Presumably another process
will eventually create the file.)
.SH
2.7\ Control\ flow\ -\ if
.LP
Also available is a
general conditional branch
of the form,
.DS
	\fBif\fP \fIcommand-list
	\fBthen	\fIcommand-list
	\fBelse	\fIcommand-list
	\fBfi\fR
.DE
that tests the value returned by the last simple command
following \fBif.\fP
.LP
The \fBif\fP command may be used
in conjunction with the \fItest\fP command
to test for the existence of a file as in
.DS
	if test \(mif file
	then	\fIprocess file\fP
	else	\fIdo something else\fP
	fi
.DE
.LP
An example of the use of \fBif, case\fP
and \fBfor\fP constructions is given in
section 2.10\|.
.LP
A multiple test \fBif\fP command
of the form
.DS
	if \*(ZZ
	then	\*(ZZ
	else	if \*(ZZ
		then	\*(ZZ
		else	if \*(ZZ
			\*(ZZ
			fi
		fi
	fi
.DE
may be written using an extension of the \fBif\fP
notation as,
.DS
	if \*(ZZ
	then	\*(ZZ
	elif	\*(ZZ
	then	\*(ZZ
	elif	\*(ZZ
	\*(ZZ
	fi
.DE
.LP
The following example is the \fItouch\fP command
which changes the `last modified' time for a list
of files.
The command may be used in conjunction
with \fImake\fP (1) to force recompilation of a list
of files.
.DS
	flag=
	for i
	do case $i in
	\*(DC\(mic)	flag=N ;;
	\*(DC\*(ST)	if test \(mif $i
	\*(DC	then	ln $i junk$$; rm junk$$
	\*(DC	elif test $flag
	\*(DC	then	echo file \\\\\'$i\\\\\' does not exist
	\*(DC	else	>$i
	\*(DC	fi
	\*(DO esac
	done
.DE
The \fB\(mic\fP flag is used in this command to
force subsequent files to be created if they do not already exist.
Otherwise, if the file does not exist, an error message is printed.
The shell variable \fIflag\fP
is set to some non-null string if the \fB\(mic\fP
argument is encountered.
The commands
.DS
	ln \*(ZZ; rm \*(ZZ
.DE
make a link to the file and then remove it
thus causing the last modified date to be updated.
.LP
The sequence
.DS
	if command1
	then	command2
	fi
.DE
may be written
.DS
	command1 && command2
.DE
Conversely,
.DS
	command1 \*(VT\*(VT command2
.DE
executes \fIcommand2\fP only if \fIcommand1\fP
fails.
In each case the value returned
is that of the last simple command executed.
.SH
2.8\ Command\ grouping
.LP
Commands may be grouped in two ways,
.DS
	\fB{\fI command-list\fB ; }\fR
.DE
and
.DS
	\fB(\fI command-list\fB )\fR
.DE
.LP
In the first \fIcommand-list\fP is simply executed.
The second form executes \fIcommand-list\fP
as a separate process.
For example,
.DS
	(cd x; rm junk )
.DE
executes \fIrm junk\fP in the directory
\fBx\fP without changing the current
directory of the invoking shell.
.LP
The commands
.DS
	cd x; rm junk
.DE
have the same effect but leave the invoking
shell in the directory \fBx.\fP
.SH
2.9\ Debugging\ shell\ procedures
.LP
The shell provides two tracing mechanisms
to help when debugging shell procedures.
The first is invoked within the procedure
as
.DS
	set \(miv
.DE
(\fBv\fP for verbose) and causes lines of the
procedure to be printed as they are read.
It is useful to help isolate syntax errors.
It may be invoked without modifying the procedure
by saying
.DS
	sh \(miv proc \*(ZZ
.DE
where \fIproc\fP is the name of the shell procedure.
This flag may be used in conjunction
with the \fB\(min\fP flag which prevents
execution of subsequent commands.
(Note that saying \fIset \(min\fP at a terminal
will render the terminal useless
until an end-of-file is typed.)
.LP
The command
.DS
	set \(mix
.DE
will produce an execution
trace.
Following parameter substitution
each command is printed as it is executed.
(Try these at the terminal to see
what effect they have.)
Both flags may be turned off by saying
.DS
	set \(mi
.DE
and the current setting of the shell flags is available as \fB$\(mi\|.\fR
.SH
2.10\ The\ man\ command
.LP
The following is the \fIman\fP command
which is used to print sections of the UNIX manual.
It is called, for example, as
.DS
		man sh
		man \(mit ed
		man 2 fork
.DE
In the first the manual section for \fIsh\fP
is printed.
Since no section is specified, section 1 is used.
The second example will typeset (\fB\(mit\fP option)
the manual section for \fIed.\fP
The last prints the \fIfork\fP manual page
from section 2.
.sp .5v
.DS
	cd /usr/man
	: \'colon is the comment command\'
	: \'default is nroff ($N), section 1 ($s)\'
	N=n\ s=1
	for i
	do case $i in
	\*(DC[1\(mi9]\*(ST)	s=$i ;;
	\*(DC\(mit)	N=t ;;
	\*(DC\(min)	N=n ;;
	\*(DC\(mi\*(ST)	echo unknown flag \\\\\'$i\\\\\' ;;
	\*(DC\*(ST)	if test \(mif man$s/$i.$s
	\*(DC	then	${N}roff man0/${N}aa man$s/$i.$s
	\*(DC	else	: \'look through all manual sections\'
	\*(DC		found=no
	\*(DC		for j in 1 2 3 4 5 6 7 8 9
	\*(DC		do if test \(mif man$j/$i.$j
	\*(DC		\*(DOthen man $j $i
	\*(DC		\*(DO\*(THfound=yes
	\*(DC		\*(DOfi
	\*(DC		done
	\*(DC		case $found in
	\*(DC		\*(Cano) echo \\'$i: manual page not found\\'
	\*(DC		esac
	\*(DC	fi
	\*(DOesac
	done
.sp .5v
.ft B
.ce
Figure 1.  A version of the man command
.ft
.DE
.SH
3.0\ Keyword\ parameters
.LP
Shell variables may be given values
by assignment
or when a shell procedure is invoked.
An argument to a shell procedure of the form
\fIname=value\fP
that precedes the command name
causes \fIvalue\fP
to be assigned to \fIname\fP
before execution of the procedure begins.
The value of \fIname\fP in the invoking
shell is not affected.
For example,
.DS
	user=fred\ command
.DE
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
.LP
The \fIset\fP command
may also be used to set positional parameters
from within a procedure.
For example,
.DS
	set\ \(mi\ \*(ST
.DE
will set \fB$1\fP to the first file name
in the current directory, \fB$2\fP to the next,
and so on.
Note that the first argument, \(mi, ensures correct treatment
when the first file name begins with a \(mi\|.
.LP
.SH
3.1\ Parameter\ transmission
.LP
When a shell procedure is invoked both positional
and keyword parameters may be supplied with the call.
Keyword parameters are also made available implicitly
to a shell procedure
by specifying in advance that such parameters
are to be exported.
For example,
.DS
	export\ user\ box
.DE
marks the variables \fBuser\fP and \fBbox\fP
for export.
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.
It is generally true of
a shell procedure
that it
may not modify the state
of its caller without explicit
request on the part of the caller.
(Shared file descriptors are an
exception to this rule.)
.LP
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
command,
.DS
	readonly name \*(ZZ
.DE
Subsequent attempts to set readonly variables
are illegal.
.SH
3.2\ Parameter\ substitution
.LP
If a shell parameter is not set
then the null string is substituted for it.
For example, if the variable \fBd\fP
is not set
.DS
	echo $d
.DE
or
.DS
	echo ${d}
.DE
will echo nothing.
A default string may be given
as in
.DS
	echo ${d\(mi\fB.\fR}
.DE
which will echo
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
.DS
	echo ${d\(mi\'\*(ST\'}
.DE
will echo \fB\*(ST\fP if the variable \fBd\fP
is not set.
Similarly
.DS
	echo ${d\(mi$1}
.DE
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
using
the notation
.DS
	echo ${d=\fB.\fR}
.DE
which substitutes the same string as
.DS
	echo ${d\(mi\fB.\fR}
.DE
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.)
.LP
If there is no sensible default then
the notation
.DS
	echo ${d?message}
.DE
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
is printed.
A shell procedure that requires some parameters
to be set might start as follows.
.DS
	:\ ${user?}\ ${acct?}\ ${bin?}
	\*(ZZ
.DE
Colon (\fB:\fP) is a command
that is
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.
.SH
3.3\ Command\ substitution
.LP
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
\fB/usr/fred/bin\fR
then the command
.DS
	d=\`pwd\`
.DE
is equivalent to
.DS
	d=/usr/fred/bin
.DE
.LP
The entire string between grave accents (\`\*(ZZ\`)
is taken as the command
to be executed
and is replaced with the output from
the command.
The command is written using the usual
quoting conventions
except that a \fB\`\fR must be escaped using
a \fB\\\|.\fR
For example,
.DS
	ls \`echo "$1"\`
.DE
is equivalent to
.DS
	ls $1
.DE
Command substitution occurs in all contexts
where parameter substitution occurs (including \fIhere\fP documents) and the
treatment of the resulting text is the same
in both cases.
This mechanism allows string
processing commands to be used within
shell procedures.
An example of such a command is \fIbasename\fP
which removes a specified suffix from a string.
For example,
.DS
	basename main\fB.\fPc \fB.\fPc
.DE
will print the string \fImain\|.\fP
Its use is illustrated by the following
fragment from a \fIcc\fP command.
.DS
	case $A in
	\*(Ca\*(ZZ
	\*(Ca\*(ST\fB.\fPc)	B=\`basename $A \fB.\fPc\`
	\*(Ca\*(ZZ
	esac
.DE
that sets \fBB\fP to the part of \fB$A\fP
with the suffix \fB.c\fP stripped.
.LP
Here are some composite examples.
.RS
.IP \(bu
.ft B
for i in \`ls \(mit\`; do \*(ZZ
.ft R
.br
The variable \fBi\fP is set
to the names of files in time order,
most recent first.
.IP \(bu
.ft B
set \`date\`; echo $6 $2 $3, $4
.ft R
.br
will print, e.g.,
.ft I
1977 Nov 1, 23:59:59
.ft R
.RE
.SH
3.4\ Evaluation\ and\ quoting
.LP
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.
.LP
Commands are parsed initially according to the grammar
given in appendix A.
Before a command is executed
the following
substitutions occur.
.RS
.IP \(bu
parameter substitution, e.g. \fB$user\fP
.IP \(bu
command substitution, e.g. \fB\`pwd\`\fP
.RS
.LP
Only one evaluation occurs so that if, for example, the value of the variable
\fBX\fP
is the string \fI$y\fP
then
.DS
	echo $X
.DE
will echo \fI$y\|.\fP
.RE
.IP \(bu
blank interpretation
.RS
.LP
Following the above substitutions
the resulting characters
are broken into non-blank words (\fIblank interpretation\fP).
For this purpose `blanks' are the characters of the string
\fB$\s-1IFS\s0\fP.
By default, this string consists of blank, tab and newline.
The null string
is not regarded as a word unless it is quoted.
For example,
.DS
	echo \'\'
.DE
will pass on the null string as the first argument to \fIecho\fP,
whereas
.DS
	echo $null
.DE
will call \fIecho\fR with no arguments
if the variable \fBnull\fP is not set
or set to the null string.
.RE
.IP \(bu
file name generation
.RS
.LP
Each word
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.
.RE
.RE
.LP
The evaluations just described also occur
in the list of words associated with a \fBfor\fP
loop.
Only substitution occurs
in the \fIword\fP used
for a \fBcase\fP branch.
.LP
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
of blanks does not.
The following characters
have a special meaning within double quotes
and may be quoted using \fB\\\|.\fP
.DS
	\fB$	\fPparameter substitution
	\fB\`\fP	command substitution
	\fB"\fP	ends the quoted string
	\fB\e\fP	quotes the special characters \fB$ \` " \e\fP
.DE
For example,
.DS
	echo "$x"
.DE
will pass the value of the variable \fBx\fP as a
single argument to \fIecho.\fP
Similarly,
.DS
	echo "$\*(ST"
.DE
will pass the positional parameters as a single
argument and is equivalent to
.DS
	echo "$1 $2 \*(ZZ"
.DE
The notation \fB$@\fP
is the same as \fB$\*(ST\fR
except when it is quoted.
.DS
	echo "$@"
.DE
will pass the positional parameters, unevaluated, to \fIecho\fR
and is equivalent to
.DS
	echo "$1" "$2" \*(ZZ
.DE
.LP
The following table gives, for each quoting mechanism,
the shell metacharacters that are evaluated.
.DS
.ce
.ft I
metacharacter
.ft
.in 1.5i
	\e	$	*	\`	"	\'
\'	n	n	n	n	n	t
\`	y	n	n	t	n	n
"	y	y	n	y	t	n
.sp
	t	terminator
	y	interpreted
	n	not interpreted
.in
.sp .5v
.ft B
.ce
Figure 2.  Quoting mechanisms
.ft
.DE
.LP
In cases where more than one evaluation of a string
is required the built-in command \fIeval\fP
may be used.
For example,
if the variable \fBX\fP has the value
\fI$y\fP, and if \fBy\fP has the value \fIpqr\fP
then
.DS
	eval echo $X
.DE
will echo the string \fIpqr\|.\fP
.LP
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)
executed.
For example,
.DS
	wg=\\'eval who\*(VTgrep\\'
	$wg fred
.DE
is equivalent to
.DS
	who\*(VTgrep fred
.DE
In this example,
\fIeval\fP is required
since there is no interpretation
of metacharacters, such as \*(VT\|, following
substitution.
.SH
3.5\ Error\ handling
.LP
The treatment of errors detected by
the shell depends on the type of error
and on whether the shell is being
used interactively.
An interactive shell is one whose
input and output are connected
to a terminal (as determined by
\fIgtty\fP (2)).
A shell invoked with the \fB\(mii\fP
flag is also interactive.
.LP
Execution of a command (see also 3.7) may fail
for any of the following reasons.
.IP \(bu
Input output redirection may fail.
For example, if a file does not exist
or cannot be created.
.IP \(bu
The command itself does not exist
or cannot be executed.
.IP \(bu
The command terminates abnormally,
for example, with a "bus error"
or "memory fault".
See Figure 2 below for a complete list
of UNIX signals.
.IP \(bu
The command terminates normally
but returns a non-zero exit status.
.LP
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.
.IP \(bu
Syntax errors.
e.g., if \*(ZZ then \*(ZZ done
.IP \(bu
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.
.IP \(bu
Failure of any of the built-in commands
such as \fIcd.\fP
.LP
The shell flag \fB\(mie\fP
causes the shell to terminate
if any error is detected.
.DS
1	hangup
2	interrupt
3*	quit
4*	illegal instruction
5*	trace trap
6*	IOT instruction
7*	EMT instruction
8*	floating point exception
9	kill (cannot be caught or ignored)
10*	bus error
11*	segmentation violation
12*	bad argument to system call
13	write on a pipe with no one to read it
14	alarm clock
15	software termination (from \fIkill\fP (1))
.sp .5v
.ft B
.ce
Figure 3.  UNIX signals
.ft
.DE
.LP
Those signals marked with an asterisk
produce a core dump
if not caught.
However,
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.
.SH
3.6\ Fault\ handling
.LP
Shell procedures normally terminate
when an interrupt is received from the
terminal.
The \fItrap\fP command is used
if some cleaning up is required, such
as removing temporary files.
For example,
.DS
	trap\ \'rm\ /tmp/ps$$; exit\'\ 2
.DE
sets a trap for signal 2 (terminal
interrupt), and if this signal is received
will execute the commands
.DS
	rm /tmp/ps$$; exit
.DE
\fIexit\fP is
another built-in command
that terminates execution of a shell procedure.
The \fIexit\fP is required; otherwise,
after the trap has been taken,
the shell will resume executing
the procedure
at the place where it was interrupted.
.LP
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
signal is received.
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.
.LP
The use of \fItrap\fP is illustrated
by this modified version of the \fItouch\fP
command (Figure 4).
The cleanup action is to remove the file \fBjunk$$\fR\|.
.DS
	flag=
	trap\ \'rm\ \(mif\ junk$$;\ exit\'\ 1 2 3 15
	for i
	do\ case\ $i\ in
	\*(DC\(mic)	flag=N ;;
	\*(DC\*(ST)	if\ test\ \(mif\ $i
	\*(DC	then	ln\ $i\ junk$$;\ rm\ junk$$
	\*(DC	elif\ test\ $flag
	\*(DC	then	echo\ file\ \\\\\'$i\\\\\'\ does\ not\ exist
	\*(DC	else	>$i
	\*(DC	fi
	\*(DOesac
	done
.sp .5v
.ft B
.ce
Figure 4.  The touch command
.ft
.DE
.LP
The \fItrap\fP command
appears before the creation
of the temporary file;
otherwise it would be
possible for the process
to die without removing
the file.
.LP
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
shell procedure.
.LP
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
\fInohup\fP command.
.DS
	trap \'\' 1 2 3 15
.DE
which causes \fIhangup, interrupt, quit \fRand\fI kill\fR
to be ignored both by the
procedure and by invoked commands.
.LP
Traps may be reset by saying
.DS
	trap 2 3
.DE
which resets the traps for signals 2 and 3 to their default values.
A list of the current values of traps may be obtained
by writing
.DS
	trap
.DE
.LP
The procedure \fIscan\fP (Figure 5) is an example
of the use of \fItrap\fP where there is no exit
in the trap command.
\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
waiting for input.
.DS
	d=\`pwd\`
	for\ i\ in\ \*(ST
	do\ if\ test\ \(mid\ $d/$i
	\*(DOthen\ cd\ $d/$i
	\*(DO\*(THwhile\ echo\ "$i:"
	\*(DO\*(TH\*(WHtrap\ exit\ 2
	\*(DO\*(TH\*(WHread\ x
	\*(DO\*(THdo\ trap\ :\ 2;\ eval\ $x;\ done
	\*(DOfi
	done
.sp .5v
.ft B
.ce
Figure 5.  The scan command
.ft
.DE
.LP
\fIread x\fR is a built-in command that reads one line from the
standard input
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
is received.
.SH
3.7\ Command\ execution
.LP
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
is required
and simply replaces the shell with a new command.
For example, a simple version of the \fInohup\fP
command looks like
.DS
	trap \\'\\' 1 2 3 15
	exec $\*(ST
.DE
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
specified.
.LP
Most forms of input output redirection have already been
described.
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,
.DS
		echo \*(ZZ >\*(ST.c
.DE
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.
.IP >\ \fIword\fP 12
The standard output (file descriptor 1)
is sent to the file \fIword\fP which is
created if it does not already exist.
.IP \*(AP\ \fIword\fP 12
The standard output is sent to file \fIword.\fP
If the file exists then output is appended
(by seeking to the end);
otherwise the file is created.
.IP <\ \fIword\fP 12
The standard input (file descriptor 0)
is taken from the file \fIword.\fP
.IP \*(HE\ \fIword\fP 12
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
of the document occurs.
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
of \fIword.\fP
In the latter case \fB\\newline\fP is ignored (c.f. quoted strings).
.IP >&\ \fIdigit\fP 12
The file descriptor \fIdigit\fP is duplicated using the system
call \fIdup\fP (2)
and the result is used as the standard output.
.IP <&\ \fIdigit\fP 12
The standard input is duplicated from file descriptor \fIdigit.\fP
.IP <&\(mi 12
The standard input is closed.
.IP >&\(mi 12
The standard output is closed.
.LP
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.
For example,
.DS
	\*(ZZ 2>file
.DE
runs a command with message output (file descriptor 2)
directed to \fIfile.\fP
.DS
	\*(ZZ 2>&1
.DE
runs a command with its standard output and message output
merged.
(Strictly speaking file descriptor 2 is created
by duplicating file descriptor 1 but the effect is usually to
merge the two streams.)
.LP
The environment for a command run in the background such as
.DS
	list \*(ST.c \*(VT lpr &
.DE
is modified in two ways.
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
read the same input.
Chaos would ensue
if this were not the case.
For example,
.DS
	ed file &
.DE
would allow both the editor and the shell
to read from the same input at the same time.
.LP
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
commands to terminate.
For this reason the UNIX convention
for a signal is that if it is set to 1
(ignored) then it is never changed
even for a short time.
Note that the shell command \fItrap\fP
has no effect for an ignored signal.
.SH
3.8\ Invoking\ the\ shell
.LP
The following flags are interpreted by the shell
when it is invoked.
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
.br
If the \fB\(mic\fP flag is present then
commands are read from \fIstring\|.\fP
.IP \fB\(mis\fP
If the \fB\(mis\fP flag is present or if no
arguments remain
then commands are read from the standard input.
Shell output is written to
file descriptor 2.
.IP \fB\(mii\fP
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.
.SH
Acknowledgements
.LP
The design of the shell is
based in part on the original UNIX shell\*([.3\*(.]
and the PWB/UNIX shell\*(<,\*([.4\*(.]\*(>,
some
features having been taken from both.
Similarities also exist with the
command interpreters
of the Cambridge Multiple Access System\*([.5\*(.]
and of CTSS\*(<.\*([.6\*(.]\*(>.
.LP
I would like to thank Dennis Ritchie
and John Mashey for many
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.
.SH
.]<
.ds [F 1
.]-
.ds [T UNIX for Beginners
.ds [A B. W. Kernighan
.ds [D 1978
.nr [T 0
.nr [A 0
.nr [O 0
.][ 5 bell-tm
.ds [F 2
.]-
.ds [T U\s-2NIX\s0 Programmer's Man\&ual
.ds [A K. Thompson
.as [A " and D. M. Ritchie
.ds [K unix
.ds [I Bell Laboratories
.ds [O Seventh Edition.
.ds [D 1978
.nr [T 0
.nr [A 0
.nr [O 1
.][ 2 book
.ds [F 3
.]-
.ds [A K. Thompson
.ds [T The U\s-2NIX\s0 Command Language
.ds [B Structured Programming\(emInfotech State of the Art Report
.ds [I Infotech International Ltd.
.ds [C Nicholson House, Maidenhead, Berkshire, England
.ds [D March 1975
.ds [P 375-384
.nr [P 1
.ds [K unix
.nr [T 0
.nr [A 0
.nr [O 0
.][ 3 article-in-book
.ds [F 4
.]-
.ds [A J. R. Mashey
.ds [T PWB/UNIX Shell Tutorial
.ds [D September 30, 1977
.nr [T 0
.nr [A 0
.nr [O 0
.][ 5 bell-tm
.ds [F 5
.]-
.ds [A D. F. Hartley (Ed.)
.ds [T The Cambridge Multiple Access System \- Users Reference Manual
.ds [I University Mathematical Laboratory
.ds [C Cambridge, England
.ds [D 1968
.nr [T 0
.nr [A 0
.nr [O 0
.][ 2 book
.ds [F 6
.]-
.ds [A P. A. Crisman (Ed.)
.ds [T The Compatible Time-Sharing System
.ds [I M.I.T. Press
.ds [K whole ctss book
.ds [C Cambridge, Mass.
.ds [D 1965
.nr [T 0
.nr [A 0
.nr [O 0
.][ 2 book
.]>
.bp
.SH
Appendix\ A\ -\ Grammar
.LP
.DS
\fIitem:		word
		input-output
		name = value
.sp 0.8
simple-command: item
		simple-command item
.sp 0.8
command:	simple-command
		\fB( \fIcommand-list \fB)
		\fB{ \fIcommand-list \fB}
		\fBfor \fIname \fBdo \fIcommand-list \fBdone
		\fBfor \fIname \fBin \fIword \*(ZZ \fBdo \fIcommand-list \fBdone
		\fBwhile \fIcommand-list \fBdo \fIcommand-list \fBdone
		\fBuntil \fIcommand-list \fBdo \fIcommand-list \fBdone
		\fBcase \fIword \fBin \fIcase-part \*(ZZ \fBesac
		\fBif \fIcommand-list \fBthen \fIcommand-list \fIelse-part \fBfi
.sp 0.8
\fIpipeline:		command
		pipeline \fB\*(VT\fI command
.sp 0.8
andor:		pipeline
		andor \fB&&\fI pipeline
		andor \fB\*(VT\*(VT\fI pipeline
.sp 0.8
command-list:	andor
		command-list \fB;\fI
		command-list \fB&\fI
		command-list \fB;\fI andor
		command-list \fB&\fI andor
.sp 0.8
input-output:	\fB> \fIfile
		\fB< \fIfile
		\fB\*(AP \fIword
		\fB\*(HE \fIword
.sp 0.8
file:		word
		\fB&\fI digit
		\fB&\fI \(mi
.sp 0.8
case-part:	pattern\fB ) \fIcommand-list\fB ;;
.sp 0.8
\fIpattern:		word
		pattern \fB\*(VT\fI word
.sp 0.8
\fIelse-part:	\fBelif \fIcommand-list\fB then\fI command-list else-part\fP
		\fBelse \fIcommand-list\fI
		empty
.sp 0.8
empty:
.sp 0.8
word:		\fRa sequence of non-blank characters\fI
.sp 0.8
name:		\fRa sequence of letters, digits or underscores starting with a letter\fI
.sp 0.8
digit:		\fB0 1 2 3 4 5 6 7 8 9\fP
.DE
.LP
.bp
.SH
Appendix\ B\ -\ Meta-characters\ and\ Reserved\ Words
.LP
a) syntactic
.RS
.IP \fB\*(VT\fR 6
pipe symbol
.IP \fB&&\fR 6
`andf' symbol
.IP \fB\*(VT\*(VT\fR 6
`orf' symbol
.IP \fB;\fP 6
command separator
.IP \fB;;\fP 6
case delimiter
.IP \fB&\fP 6
background commands
.IP \fB(\ )\fP 6
command grouping
.IP \fB<\fP 6
input redirection
.IP \fB\*(HE\fP 6
input from a here document
.IP \fB>\fP 6
output creation
.IP \fB\*(AP\fP 6
output append
.sp 2
.RE
.LP
b) patterns
.RS
.IP \fB\*(ST\fP 6
match any character(s) including none
.IP \fB?\fP 6
match any single character
.IP \fB[...]\fP 6
match any of the enclosed characters
.sp 2
.RE
.LP
c) substitution
.RS
.IP \fB${...}\fP 6
substitute shell variable
.IP \fB\`...\`\fP 6
substitute command output
.sp 2
.RE
.LP
d) quoting
.RS
.IP \fB\e\fP 6
quote the next character
.IP \fB\'...\'\fP 6
quote the enclosed characters except for \'
.IP \fB"\&..."\fR 6
quote the enclosed characters except
for \fB$ \` \e "\fP
.sp 2
.RE
.LP
e) reserved words
.DS
.ft B
if then else elif fi
case in esac
for while until do done
{  }
.ft
.DE
.sp
.I "May 1979"