977 lines
26 KiB
Text
977 lines
26 KiB
Text
|
.\" $NetBSD: t3,v 1.3 2010/08/22 02:19:07 perry Exp $
|
||
|
.\"
|
||
|
.\" Copyright (C) Caldera International Inc. 2001-2002. All rights reserved.
|
||
|
.\"
|
||
|
.\" Redistribution and use in source and binary forms, with or without
|
||
|
.\" modification, are permitted provided that the following conditions are
|
||
|
.\" met:
|
||
|
.\"
|
||
|
.\" Redistributions of source code and documentation must retain the above
|
||
|
.\" copyright notice, this list of conditions and the following
|
||
|
.\" disclaimer.
|
||
|
.\"
|
||
|
.\" Redistributions in binary form must reproduce the above copyright
|
||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||
|
.\" documentation and/or other materials provided with the distribution.
|
||
|
.\"
|
||
|
.\" All advertising materials mentioning features or use of this software
|
||
|
.\" must display the following acknowledgement:
|
||
|
.\"
|
||
|
.\" This product includes software developed or owned by Caldera
|
||
|
.\" International, Inc. Neither the name of Caldera International, Inc.
|
||
|
.\" nor the names of other contributors may be used to endorse or promote
|
||
|
.\" products derived from this software without specific prior written
|
||
|
.\" permission.
|
||
|
.\"
|
||
|
.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
|
||
|
.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
||
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
.\" DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
|
||
|
.\" FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
|
.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
|
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||
|
.\" OR OTHERWISE) RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||
|
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
.\"
|
||
|
.\" @(#)t3 8.1 (Berkeley) 6/8/93
|
||
|
.\"
|
||
|
.SH
|
||
|
3.0\ Keyword\ parameters
|
||
|
.LP
|
||
|
Shell variables may be given values
|
||
|
by assignment
|
||
|
or when a shell script is invoked.
|
||
|
An argument to a command of the form
|
||
|
\fIname=value\fP
|
||
|
that precedes the command name
|
||
|
causes \fIvalue\fP
|
||
|
to be assigned to \fIname\fP
|
||
|
before execution of the command 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.
|
||
|
.\" Removed by Perry Metzger because -k is not in POSIX
|
||
|
.\"
|
||
|
.\" 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 script.
|
||
|
For example,
|
||
|
.DS
|
||
|
set\ \(mi\(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\(mi, ensures correct treatment
|
||
|
when the first file name begins with a \(mi\|.
|
||
|
.LP
|
||
|
.SH
|
||
|
3.1\ Parameter\ transmission
|
||
|
.LP
|
||
|
When a command is executed both positional parameters
|
||
|
and shell variables may be set on invocation.
|
||
|
Variables are also made available implicitly
|
||
|
to a command
|
||
|
by specifying in advance that such parameters
|
||
|
are to be exported from the invoking shell.
|
||
|
For example,
|
||
|
.DS
|
||
|
export\ user\ box=red
|
||
|
.DE
|
||
|
marks the variables \fBuser\fP and \fBbox\fP
|
||
|
for export (setting \fBbox\fP to ``red'' in the process).
|
||
|
When a command is invoked
|
||
|
copies are made of all exportable variables
|
||
|
(also known as \fIenvironment variables\fP)
|
||
|
for use within the invoked program.
|
||
|
Modification of such variables
|
||
|
within an invoked command does not
|
||
|
affect the values in the invoking shell.
|
||
|
It is generally true of
|
||
|
a shell script or other program
|
||
|
that it
|
||
|
cannot modify the state
|
||
|
of its caller without explicit
|
||
|
actions on the part of the caller.
|
||
|
.\" Removed by Perry Metzger because this is confusing to beginners.
|
||
|
.\"
|
||
|
.\" (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[=value] \*(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 not null 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 or null.
|
||
|
Similarly
|
||
|
.DS
|
||
|
echo ${d:\(mi$1}
|
||
|
.DE
|
||
|
will echo the value of \fBd\fP if it is set and not null
|
||
|
and the value (if any) of \fB$1\fP otherwise.
|
||
|
.LP
|
||
|
The notation ${d:+\fB.\fR} performs the inverse operation. It
|
||
|
substitutes `\fB.\fP' if \fBd\fP is set or not null, and otherwise
|
||
|
substitutes null.
|
||
|
.LP
|
||
|
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 or null
|
||
|
then it will be set to the string `\fB.\fP'\|.
|
||
|
.LP
|
||
|
If there is no sensible default then
|
||
|
the notation
|
||
|
.DS
|
||
|
echo ${d:?\fImessage\fP}
|
||
|
.DE
|
||
|
will echo the value of the variable \fBd\fP if it is set and not null,
|
||
|
otherwise \fImessage\fP is printed by the shell and
|
||
|
execution of the shell script is abandoned.
|
||
|
If \fImessage\fP is absent then a standard message
|
||
|
is printed.
|
||
|
A shell script that requires some variables
|
||
|
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 script.
|
||
|
.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 commands
|
||
|
.DS
|
||
|
d=$(pwd)
|
||
|
.DE
|
||
|
(or the older notation d=\`pwd\`)
|
||
|
is equivalent to
|
||
|
.DS
|
||
|
d=/usr/fred/bin
|
||
|
.DE
|
||
|
.LP
|
||
|
The entire string inside $(\*(ZZ)\| (or between grave accents \`\*(ZZ\`)
|
||
|
is taken as the command
|
||
|
to be executed
|
||
|
and is replaced with the output from
|
||
|
the command.
|
||
|
(The difference between the $(\*(ZZ) and \`\*(ZZ\` notations is that
|
||
|
the former may be nested, while the latter cannot be.)
|
||
|
.LP
|
||
|
The command is written using the usual quoting conventions,
|
||
|
except that inside \`\*(ZZ\`
|
||
|
a \fB\`\fR must be escaped using
|
||
|
a \fB\\\|\fR.
|
||
|
For example,
|
||
|
.DS
|
||
|
ls $(echo "$HOME")
|
||
|
.DE
|
||
|
is equivalent to
|
||
|
.DS
|
||
|
ls $HOME
|
||
|
.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 scripts.
|
||
|
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 \(mi\(mi\| \`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\ Arithmetic\ Expansion
|
||
|
.LP
|
||
|
Within a $((\*(ZZ)) construct, integer arithmetic operations are
|
||
|
evaluated.
|
||
|
(The $ in front of variable names is optional within $((\*(ZZ)).
|
||
|
For example:
|
||
|
.DS
|
||
|
x=5; y=1
|
||
|
echo $(($x+3*2))
|
||
|
echo $((y+=x))
|
||
|
echo $y
|
||
|
.DE
|
||
|
will print `11', then `6', then `6' again.
|
||
|
Most of the constructs permitted in C arithmetic operations are
|
||
|
permitted though some (like `++') are not universally supported \(em
|
||
|
see the shell manual page for details.
|
||
|
.SH
|
||
|
3.5\ 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 or \fB\`pwd\`\fP
|
||
|
.IP \(bu
|
||
|
arithmetic expansion, e.g. \fB$(($count+1))\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 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
|
||
|
|
||
|
t terminator
|
||
|
y interpreted
|
||
|
n not interpreted
|
||
|
|
||
|
.in
|
||
|
.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 \fB\*(VT\|\fR, following
|
||
|
substitution.
|
||
|
.SH
|
||
|
3.6\ 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.
|
||
|
.\" Removed by Perry Metzger, obsolete and excess detail
|
||
|
.\"
|
||
|
.\" (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 script.
|
||
|
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))
|
||
|
|
||
|
.DE
|
||
|
.ft B
|
||
|
.ce
|
||
|
Figure 3. UNIX signals\(dg
|
||
|
.ft
|
||
|
.FS
|
||
|
\(dg Additional signals have been added in modern Unix.
|
||
|
See \fIsigvec\fP(2) or \fIsignal\fP(3) for an up-to-date list.
|
||
|
.FE
|
||
|
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.7\ Fault\ handling
|
||
|
.LP
|
||
|
shell scripts 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 script.
|
||
|
The \fIexit\fP is required; otherwise,
|
||
|
after the trap has been taken,
|
||
|
the shell will resume executing
|
||
|
the script
|
||
|
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 script, 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
|
||
|
#!/bin/sh
|
||
|
|
||
|
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 cp\ $i\ junk$$;\ mv\ junk$$ $i
|
||
|
\*(DC elif\ test\ $flag
|
||
|
\*(DC then echo\ file\ \\'$i\\'\ does\ not\ exist
|
||
|
\*(DC else >$i
|
||
|
\*(DC fi
|
||
|
\*(DOesac
|
||
|
done
|
||
|
.DE
|
||
|
.sp
|
||
|
.ft B
|
||
|
.ce
|
||
|
Figure 4. The touch command
|
||
|
.ft
|
||
|
.sp
|
||
|
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 script.
|
||
|
.LP
|
||
|
A script 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
|
||
|
script 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 script \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
|
||
|
.DE
|
||
|
.sp
|
||
|
.ft B
|
||
|
.ce
|
||
|
Figure 5. The scan command
|
||
|
.ft
|
||
|
.sp
|
||
|
\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.8\ 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.)
|
||
|
.\" Removed by Perry Metzger, most of this is now obsolete
|
||
|
.\"
|
||
|
.\" .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.9\ 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
|
||
|
3.10\ Job\ Control
|
||
|
.LP
|
||
|
When a command or pipeline (also known as a \fIjob\fP) is running in
|
||
|
the foreground, entering the stop character (typically
|
||
|
\s-1CONTROL-Z\s0 but user settable with the \fIstty\fP(1) command)
|
||
|
will usually cause the job to stop.
|
||
|
.LP
|
||
|
The jobs associated with the current shell may be listed by entering
|
||
|
the \fIjobs\fP command.
|
||
|
Each job has an associated \fIjob number\fP.
|
||
|
Jobs that are stopped may be continued by entering
|
||
|
.DS
|
||
|
bg %\fIjobnumber\fP
|
||
|
.DE
|
||
|
and jobs may be moved to the foreground by entering
|
||
|
.DS
|
||
|
fg %\fIjobnumber\fP
|
||
|
.DE
|
||
|
If there is a sole job with a particular name (say only one instance
|
||
|
of \fIcc\fP running), \fIfg\fP and \fIbg\fP may also use name of the
|
||
|
command in place of the number, as in:
|
||
|
.DS
|
||
|
bg %cc
|
||
|
.DE
|
||
|
If no `\fB%\fP' clause is entered, most recently stopped job
|
||
|
(indicated with a `+' by the \fIjobs\fP command) will be assumed.
|
||
|
See the manual page for the shell for more details.
|
||
|
.SH
|
||
|
3.11\ Aliases
|
||
|
.LP
|
||
|
The \fIalias\fP command creates a so-called shell alias, which is an
|
||
|
abbreviation that macro-expands at run time into some other command.
|
||
|
For example:
|
||
|
.DS
|
||
|
alias ls="ls -F"
|
||
|
.DE
|
||
|
would cause the command sequence \fBls -F\fP to be executed whenever
|
||
|
the user types \fBls\fP into the shell.
|
||
|
Note that if the user types \fBls -a\fP, the shell will in fact
|
||
|
execute \fBls -F -a\fP.
|
||
|
The command \fBalias\fP on its own prints out all current aliases.
|
||
|
The \fIunalias\fP command, as in:
|
||
|
.DS
|
||
|
unalias ls
|
||
|
.DE
|
||
|
will remove an existing alias.
|
||
|
Aliases can shadow pre-existing commands, as in the example above.
|
||
|
They are typically used to override the interactive behavior of
|
||
|
commands in small ways, for example to always invoke some program with
|
||
|
a favorite option, and are almost never found in scripts.
|
||
|
.SH
|
||
|
3.12\ Command\ Line\ Editing\ and\ Recall
|
||
|
.LP
|
||
|
When working interactively with the shell, it is often tedious to
|
||
|
retype previously entered commands, especially if they are complicated.
|
||
|
The shell therefore maintains a so-called \fIhistory\fP, which is
|
||
|
stored in the file specified by the \fB\s-1HISTFILE\s0\fP environment
|
||
|
variable if it is set.
|
||
|
Users may view, edit, and re-enter previous lines of input using
|
||
|
a small subset of the commands of the \fIvi\fP(1) or
|
||
|
\fIemacs\fP(1)\(dg editors.
|
||
|
.FS
|
||
|
Technically, vi command editing is standardized by POSIX while emacs
|
||
|
is not.
|
||
|
However, all modern shells support both styles.
|
||
|
.FE
|
||
|
Emacs style editing may be selected by entering
|
||
|
.DS
|
||
|
set -o emacs
|
||
|
.DE
|
||
|
and vi style editing may be selected with
|
||
|
.DS
|
||
|
set -o vi
|
||
|
.DE
|
||
|
The details of how command line editing works are beyond the scope of
|
||
|
this document.
|
||
|
See the shell manual page for details.
|
||
|
.SH
|
||
|
Acknowledgements
|
||
|
.LP
|
||
|
The design of the shell is
|
||
|
based in part on the original UNIX shell
|
||
|
.[
|
||
|
unix command language thompson
|
||
|
.]
|
||
|
and the PWB/UNIX shell,
|
||
|
.[
|
||
|
pwb shell mashey unix
|
||
|
.]
|
||
|
some
|
||
|
features having been taken from both.
|
||
|
Similarities also exist with the
|
||
|
command interpreters
|
||
|
of the Cambridge Multiple Access System
|
||
|
.[
|
||
|
cambridge multiple access system hartley
|
||
|
.]
|
||
|
and of CTSS.
|
||
|
.[
|
||
|
ctss
|
||
|
.]
|
||
|
.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
|
||
|
.[
|
||
|
$LIST$
|
||
|
.]
|