sh(1) sh(1)
NAME
sh, bg, break, chdir, continue, fg, jobs, return, stop, suspend -
Bourne shell, a command interpreter and programming language
SYNOPSIS
sh [option ...] [file] [argument ...]
DESCRIPTION
The description of the Bourne shell is divided into three main parts:
⊕ the sh command
- login shell and subshells
- options
⊕ the shell as command interpreter
- entering and grouping commands
- shell metanotation
- shell variables
- environment
- shell parameters
- command substitution
- input/output redirection
- file name generation
- command line processing
⊕ the shell as programming language
- comments in shell scripts
- shell functions
- shell control-flow statements
Page 1 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
THE SH COMMAND
The shell is the user interface to the operating system kernel. It is
implemented as a Reliant UNIX command and is not part of the kernel;
the shell and all other Reliant UNIX commands communicate with the
kernel via system calls.
The sh is a Bourne shell and has the following basic functions:
- it takes input from a terminal or a file, interprets the input
according to defined rules, and has the appropriate commands exe-
cuted. A file containing input for the shell is called a shell pro-
cedure or shell script.
- it serves as a programming language. This means that you can create
your own programs from existing Reliant UNIX commands and execute
them without needing to compile them first.
Login shell
When you log in at a terminal, this shell is started up by default by
login(1). The login shell is associated with the calling terminal,
i.e. the file descriptors 0 for standard input, 1 for standard output,
and 2 for standard error output are specific to this terminal. The
following steps are performed sequentially before the login shell
displays its prompt:
- The login shell assigns default values to the standard shell vari-
ables HOME, IFS, MAIL, MAILCHECK, PATH, PS1, PS2 and SHELL (see
SHELL VARIABLES below).
- The file /etc/profile is executed.
- The file $HOME/.profile is executed if you have created one.
You have to be in a login shell in order to log in with the Bourne
shell built-in login(1), and even then it is only possible to log in
as root.
You can find out if you are in a login shell as follows: The command
echo $0 displays the invocation name of the current shell; -sh identi-
fies a login shell, sh a normal subshell.
A login shell is started as a subshell whenever you log into the sys-
tem (again) with /bin/login (see Subshells below).
To exit from a login shell you press CTRL-D. If the login shell was
not a subshell, the welcome screen is then displayed; your session has
then terminated.
Page 2 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Subshells
You can use sh to call a new shell, known as a subshell. This shell is
associated with the same terminal as its parent shell, and it inherits
all shell variables that you have defined and exported in the parent
shell and any shells above it [see export(1) and option -a]. Shell
variables can only be passed from the current shell to subshells, not
to the parent shell.
Unlike the login shell, the subshell does not execute /etc/profile or
$HOME/.profile. This means that you can define or modify shell vari-
ables and switch directories in a subshell without affecting the
parent shell. When the subshell exits, the parent shell returns in the
state it was in when it started the subshell.
The Bourne shell built-in login(1) is rejected if you try to use it in
a subshell. You have to be in a login shell if you want to use login.
The sh command allows you to control the behavior of the new subshell
on the basis of the operands which you specify on the command line. If
you give a file name, the subshell exits after executing the file. If
you do not give a file name, the subshell is interactive: it reads
input from the terminal until you terminate it by pressing CTRL-D. A
shell running a shell script is not interactive (see also option -i).
OPTIONS
No operand specified:
A subshell is invoked with the -s option. The previously active
shell process becomes the parent of the new shell. This new shell
can be terminated with CTRL-D.
No option specified:
If you call sh with operands that are not options, file must be
the first operand specified. file stands for the name of a shell
script for which you will need to have read permission.
A subshell is then created. This subshell will execute the com-
mands in the named shell script one after the other and then
exit.
The options govern the behavior of the invoked subshell.
If you want to use more than one option, you have to group the code
letters together with no spaces between them and with a single minus
sign at the beginning.
The -- option cannot be combined with other options.
The -c command option, if selected, must be the last option specified,
but the other options can appear in any order.
Page 3 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The behavior of the current shell can be controlled by using the
Bourne shell built-in set(1).
There are two types of option:
- options that you can only specify with sh;
- options that you can also specify with the Bourne shell built-in
set [also refer to set(1)].
Options for sh only
-c command
The subshell executes command and terminates. This option must be
the last option you specify on the command line, and it must not
be followed by any other operands either.
The -c command option allows you to invoke commands within a C
program.
command is mandatory; omitting it produces an error message.
command
Must be a command-line argument. If the command you want to
run contains blanks or tabs, you have to enclose it in sin-
gle or double quotes. Otherwise the shell will stop inter-
preting it at the first blank.
command is a command or executable shell script for which
you will need to have read and write permission. It is run
in the invoked (forked) subshell.
If you want to include a number of commands and/or shell
scripts, you will have to escape the command separators.
If you use the basic file name (file basename) for the
command/shell script, the shell looks for the file in the
directories whose full path names are assigned to the PATH
variable.
-i An interactive subshell is called. This shell reads input from
standard input, processes it, starts the corresponding commands,
and waits for them to terminate. Then it displays its prompt and
is ready to process further input. An interactive shell responds
to signal 2 for SIGINT, 3 for SIGQUIT, and 15 for SIGTERM as fol-
lows (PID is the process ID of the interactive shell):
Page 4 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
__________________________________________________________________
| Signal | Sent by | Interactive shell |
|_________|_______________|_______________________________________|
| | DEL | Command running; ignored, i.e. an |
| SIGINT | kill -2 PID | interactive shell is not terminated. |
| | | Otherwise: issues new prompt. |
|_________|_______________|_______________________________________|
| | CTRL-\ | Command running: ignored, i.e. an |
| SIGQUIT | kill -3 PID | interactive shell is not terminated. |
| | | Otherwise: issues a new prompt. |
|_________|_______________|_______________________________________|
| SIGTERM | kill -15 PID | Ignored. |
|_________|_______________|_______________________________________|
You can use option -i to invoke an interactive shell within a C
program.
-i not specified:
A shell is interactive by default if its standard input, standard
output and standard error are associated with a terminal.
A shell running a shell script is not interactive. A script shell
of this type responds to the SIGINT, SIGQUIT, and SIGTERM signals
(sent by kill -2, kill -3 and kill -15) as follows:
__________________________________________________________________
| Signal | Script shell | Script shell & |
|_________|_____________________________________|_________________|
| SIGINT | waits for termination of executing | ignored |
| | command, then exits | |
|_________|_____________________________________|_________________|
| SIGQUIT | waits for termination of executing | ignored |
| | command, then exits | |
|_________|_____________________________________|_________________|
| SIGTERM | waits for termination of executing | ignored |
| | command, then exits | |
|_________|_____________________________________|_________________|
-p (privileged) The invoked shell does not set the effective user
and group IDs to the real user and group IDs (those of the
caller), but to it own user and group IDs.
-r Calls a restricted shell, in which the following restrictions
apply:
- The Bourne shell built-in cd(1) is rejected, which means you
cannot change your current directory.
- The value of the PATH variable cannot be modified.
Page 5 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- Commands are rejected if the command file name contains a
slash. This means that you can only execute commands that are
located in your current directory or in directories whose path
names have been assigned to the PATH variable.
- Commands are rejected if the command line contains the charac-
ter > or >>. In other words, you cannot use > or >> to
redirect the output of commands to a file.
A restricted shell can only be called with sh -r. The rsh com-
mand, by contrast, is used to invoke a shell on a remote system
and not, as in earlier UNIX versions, a restricted shell.
For the system administrator only
As system administrator you can set up an environment for
users who are only to be allowed to work in a restricted
shell. For such users you define:
- The directory they are to work in.
Users should not be able to work in the login directory,
but should simply have read permission there.
- The commands they are allowed to use.
You can do this by setting up a subdirectory in the login
directory and copying the approved commands into it.
Among other things, it should not be possible to invoke a
subshell, as a subshell of a restricted shell is not re-
stricted.
- The PATH variable.
In the user's $HOME/.profile you enter the appropriate com-
mands and a call to the restricted shell. Once the login
shell has executed the .profile, the user should only be
able to work in the assigned working directory and in the
restricted shell.
-r not specified:
The described restrictions do not apply to the invoked subshell.
Page 6 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
-s The invoked subshell reads from standard input and writes on
standard error. Bourne shell built-ins will, however, continue to
write on the standard output.
The invoked subshell sequentially assigns the first nine arguments
after -s to positional parameters $1 through $9. It assigns all
command-line arguments after -s collectively to the shell parame-
ters $@ and $*; and it assigns the total number of arguments to the
shell parameter $#. If there are fewer than nine arguments, the
remaining positional parameters are set to the null string.
These values are only known to the called subshell. If positional
parameters are to be set in the current shell, the Bourne shell
built-in set(1) must be used instead.
If you also specify a file in the command line, the invoked subshell
assigns the command-line argument file to positional parameter $1,
but does not execute the commands contained in file. You cannot set
the -s option if you want to use sh to run a shell script.
-s not specified:
-s is set by default when sh is called without operands.
The login shell is always invoked with -s.
Options for sh and set
-a Automatically exports all shell variables that you define or
redefine in the called subshell.
set +a turns off option -a in this subshell.
-a not specified:
Shell variables that you define or redefine in the called sub-
shell are not automatically exported. In other words, a shell
variable will not be known in a further subshell unless you
explicitly export it using the Bourne shell built-in export(1).
-e The invoked subshell or shell script exits immediately if a com-
mand exits with a non-zero exit status.
set +e turns off option -e in this subshell.
-e not specified:
If the called subshell is interactive, you can terminate it with
CTRL-D. If it is a script shell, it only exits prematurely if it
encounters a syntax error; otherwise, it does not exit until the
last command has been executed, regardless of the exit status of
individual commands.
Page 7 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
-f Disables the file name generation mechanism in the called sub-
shell or shell script. The symbols *, ? and [...] are not treated
as metacharacters and expanded to generate all the matching file
names.
set +f turns off option -f in this subshell.
-f not specified:
Matching file names are substituted for the above patterns.
-h This option changes the behavior of the called subshell when you
define shell functions (see Example 2):
The commands you include in a shell function in the called sub-
shell are entered in the hash table at the time of function
definition [see hash(1)].
set +h turns off option -h in this subshell.
-h not specified:
Commands used in a shell function are not entered in the hash
table until the function is executed.
-k Keyword. Variable assignments, i.e. arguments in the form
name=value, are allowed at any point on the command line in the
called subshell. The called subshell performs the assignment and
makes the resultant keyword parameter available to the environ-
ment of the command.
set +k turns off option -k in this subshell.
-k not specified and not set previously:
Variable assignments must precede the command name. The shell
makes the appropriate keyword parameters available to the
environment of the command.
-n The called subshell reads and interprets all commands but does
not execute them, thus omitting the last step in the processing
of a command line (see COMMAND LINE PROCESSING below).
The -n option can be used to check a shell script for syntax
errors (see Example 1).
Caution:
You cannot explicitly turn off option -n; it is turned off
when the subshell exits.
Page 8 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
-n not specified:
All commands are read, interpreted, and executed.
-t Terminate. The called subshell exits after executing the first
command line.
If you invoke sh -t without a file operand, the subshell expects
you to enter the command to be executed in the next line; but it
does not issue a prompt.
-t not specified:
An interactive shell exits when you press CTRL-D.
A script shell only exits prematurely if it encounters a syntax
error. Otherwise, it exits on reaching the end of the script.
Caution:
If the -e option is set, the shell exits immediately if a
command returns a non- zero exit status.
-u Causes the called subshell to issue an error message on
encountering an unset shell variable in a command line. The com-
mand in question is not executed.
Shell scripts are terminated as soon as the subshell encounters
an undefined shell variable.
set +u turns off option -u in this subshell.
-u not specified:
The subshell does not issue an error message for an unset shell
variable, but substitutes the null string as its value by
default.
-v Verbose. The called subshell displays each subsequent input on
standard error before executing the corresponding command.
In combination with the -x option, this option is useful for
debugging shell scripts (see Example 1).
set +v turns off option -v in this subshell.
-v not specified:
The called subshell does not echo its input.
Page 9 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
-x The called subshell interprets its input and writes it on the
standard error, marking each command that it processes with a
plus sign (+) at the start of the line. A command consisting
solely of a variable assignment is output without the plus sign.
The shell then executes the command.
In contrast to the output with option -v, the -x option shows you
how the shell has replaced metacharacters and shell variables.
Thus you can test a shell script as follows:
- either run the shell script with the command sh -xv script, or
- include set -xv as the first command in your shell script.
set +x turns off option -x in this subshell.
-x not specified:
The called subshell does not echo its input.
-- This option cannot be combined with other options. The first
argument specified after -- is not interpreted as an option, even
if it begins with a minus sign. This enables you to use sh to run
a shell script which has a name beginning with a minus sign.
Note: In earlier versions of the shell, a single minus sign had
the same effect that a double minus sign now has, namely to mark
the end of the list of options. While a single minus sign can
still be specified today, it does not have a recognizable effect.
file Name of the shell script to be executed by the subshell. You need
read permission for this file.
If the -c command option is used, it must not be followed by any
other operands, and no file may be specified.
If you invoke sh with the -s option, the invoked subshell simply
assigns file to positional parameter $1 and does not execute the
commands contained in it.
file not specified:
The called subshell issues its prompt, reads input from the stan-
dard input and processes it in accordance with the options which
have been set.
Page 10 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
argument
Any string delimited by blanks or tabs. The last argument is ter-
minated by a command separator.
You can include any number of arguments, with at least one blank
or tab between them.
The invoked subshell sequentially assigns the first nine argu-
ments to positional parameters $1 through $9. It assigns all
command-line arguments collectively to the shell parameters $@
and $*; and it assigns the total number of arguments to the shell
parameter $#. If there are fewer than nine arguments, the remain-
ing positional parameters are set to the null string.
To access the tenth and subsequent command-line arguments
directly you need to use the shift command.
These values are only known to the called subshell. If positional
parameters are to be set in the current shell, the Bourne shell
built-in set(1) must be used instead.
argument not specified:
The null string is assigned as a value to positional parameters
$1 through $9 and to the shell parameters $@, $*, and $#.
EXIT STATUS
not equal to 0
The shell returns a non-zero status when it detects a syntax
error in the input. If the error occurs during execution of a
shell script, the script file is terminated.
In all other cases, the exit status of the last command executed is
returned.
FILES
/etc/profile
File executed by every login shell in order to set up a shell
environment. This file is created by the system administrator.
$HOME/.profile
Shell script that users can set up in their HOME directory.
$HOME/.profile is executed by the login shell after /etc/profile.
/tmp/sh*
Temporary files.
/dev/null
Null file to which the standard input is directed. This file is
typically used for background commands.
Page 11 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
ENVIRONMENT VARIABLES
See Standard shell variables below.
LOCALE
The LCMESSAGES environment variable governs the language in which
message texts are displayed.
In file name generation patterns, the LCCOLLATE environment variable
governs the scope of character ranges, equivalence classes and collat-
ing elements, and the LCCTYPE environment variable governs the scope
of character classes. The latter also determines which characters from
the currently valid character set are defined as letters.
If LCMESSAGES, LCCOLLATE or LCCTYPE is undefined or is defined as
the null string, it defaults to the value of LANG. If LANG is likewise
undefined or null, the system acts as if it were not international-
ized.
The LCALL environment variable governs the entire locale. LCALL
takes precedence over all the other environment variables which affect
internationalization.
If any of the locale variables has an invalid value, the system acts
as if none of the variables were set.
Caution:
The current character set and the current collating sequence
together determine which characters form part of a [c1-c2] range.
For example, in the locale LANG=LCCOLLATE=EnUS.ASCII the com-
mand rm [a-z]* deletes all files with names beginning with a
lowercase letter from a to z inclusive. In a number of other
locales the range a-z also include uppercase letters, and in
these environments the same command would also delete files with
names beginning with a capital letter. What is more, there are
languages, Norwegian, for example, where some letters collate
after z. So in an internationalized environment you should always
represent character classes such as lowercase letters using
expressions of the form [:class:]. Thus instead of the command
given above you would use rm [[:lower:]]*.
Shell scripts written in a non-internationalized environment (or
without allowing for the problems described above) should only be
run in a non-internationalized environment; in other words, the
NLS variables LANG, LCCOLLATE and so on should be undefined or
null.
Page 12 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
EXAMPLES
Example 1
This example searches for syntax errors in a newly created shell
script without executing the commands in it. The shell script syntax
has the following contents:
: # Invocation with sh syntax
set `echo *`
echo `pwd`:
ll {
ls -al $* | pg
}
The definition of the shell function ll contains an error; the
parentheses () have been omitted. The shell reports this syntax error
if you call syntax as follows:
$ sh -nv syntax
set `echo *`
echo `pwd`:
ll {
ls -al $* | pg
}
syntax: syntax error at line 6: `}' unexpected
Since the -v option has also been set, each read command line is addi-
tionally displayed by the shell. The individual commands are are not
executed.
Example 2
The commands in a shell function are to be entered in the hash table
at definition time rather than at runtime:
$ sh -h
$ ll() {
ls -al $* | pg
}
$ hash
hits cost command
0 2 /usr/bin/pg
0 1 /bin/ls
.
.
.
Option -h is set in the called subshell, so as soon as the ls and pg
commands are defined in the shell function ll they are also entered in
the hash table [see hash(1)].
Page 13 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
THE SHELL AS COMMAND INTERPRETER
This section has the following layout:
⊕ Entering and grouping commands
- Pipelines
- Command lists
- Command grouping (bracketing)
- Shell built-ins
⊕ Shell metanotation
⊕ Shell variables
- Defining shell variables
- Accessing the value of a variable
- Standard shell variables
⊕ The environment
- Initial environment of a command
- Runtime environment of the current shell
⊕ Shell parameters
- Substituting values for shell parameters
- Defining default values for shell parameters
⊕ Command substitution
⊕ Command input and output redirection
- Redirecting standard input for a command
- Redirecting standard output for a command
- Redirecting standard error for a command
- Multiple redirections
⊕ File name generation
⊕ Command line processing
Page 14 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Entering and grouping commands
Commands can either be collected in a file and executed as a shell
script or entered interactively at the shell prompt. The default com-
mand format is:
command parameter ...CR
command
Name of a Reliant UNIX command, shell script, Bourne shell
built-in or shell function to be executed.
parameter
Command-line argument that the shell either interprets itself or
passes on to command. Depending on the specified command, several
command-line arguments may be given.
The command name and the command-line arguments are separated by tabs
or blanks; a newline character terminates the last argument (thereby
terminating command input). It is also possible to write a number of
commands on the same line, with a command separator between them (see
Pipelines and Command lists below).
Blanks, tabs, and newline characters are assigned as default argument
separators to the IFS shell variable. The contents of the IFS variable
are evaluated in the following cases:
- when the Bourne shell built-in read(1) parses the read input line
into arguments,
- when the shell parses the modified command line into arguments for
the second time (see "Step 8" in COMMAND LINE PROCESSING below).
If you modify the value of the IFS variable, read and the shell under-
stand only your modified argument separators on the second parse run.
On the first parse run (see "Step 3" in COMMAND LINE PROCESSING
below), blanks and tabs act as argument separators, regardless of the
value of the IFS environment variable.
Every Reliant UNIX command returns its exit status to the shell in
which it was called. The usual values of the exit status are:
0 successful execution of the command
not equal to 0
if the command has failed
Interpreting single commands is, however, just one of the many facets
of the shell. For instance, you can also string commands together as
follows:
Page 15 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- Two or more commands can be linked by "pipes", represented by the
vertical bar |, to form a pipeline (see Pipelines below).
- A series of commands or pipelines can be connected to form a com-
mand list by a semicolon (;) or by an ampersand (&) or by && or ||
(see Command lists below).
Pipelines
A pipeline is a sequence of two or more commands separated by the
vertical bar character |, which forms a connection known as a pipe
between two commands.
A pipe between two commands redirects the standard output of the first
command to the standard input of the second. Commands connected in
this way must therefore satisfy the following conditions:
- The first command in a pipeline must write to standard output.
- The last command in a pipeline must read from standard input.
- If a pipeline comprises more than two commands, all intervening
commands between the first and last must read from standard input
and write to standard output. Commands that read from standard
input and write to standard output are also known as filters.
The shell starts all commands of a pipeline simultaneously as indepen-
dent parallel processes. On a single-processor system, however, only
one of these processes can be handled by the processor in any one unit
of processor time; the processor takes each process in turn.
The only process which does not receive its input from another process
is the process associated with the first command in the pipeline.
The only process which does not pass its input on to another process
is the process associated with the last command in the pipeline.
The individual processes must therefore be synchronized by the operat-
ing system kernel. The processes associated with two successive com-
mands in the pipeline communicate with one another via a buffer. The
reading process thus waits for the writing process to enter data in
the buffer; and when the buffer is full the writing process waits for
the reading process to extract the data from it.
The shell waits for the last command in the pipeline to complete and
does not process further input until this has happened.
Exit status of a pipeline
The exit status of a pipeline is the exit status of its final command.
Page 16 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Command lists
A sequence of commands or pipelines can be combined to form a command
list. The individual elements of such a list are separated by the ; or
& character or the character pair && or ||. A command list may be ter-
minated by a newline, semicolon, or ampersand. Any newline character
not enclosed within parentheses or braces causes the shell to execute
the command list (see Command grouping below).
This feature permits you to enter several commands at a time without
waiting for individual commands to terminate. The shell does not issue
its prompt until all commands in the command list have been executed.
In the following discussion, the term command encompasses both com-
mands and pipelines. The meanings of individual command separators are
given below:
______________________________________________________________________
| Symbol | Effect |
|_________|___________________________________________________________|
| ; | The shell processes the next command only after the |
| | preceding one finishes. The prompt does not appear |
| | between the two commands. |
|_________|___________________________________________________________|
| & | The shell runs the preceding command in the background |
| | and immediately processes the following command. Back- |
| | ground processes ignore the SIGINT and SIGQUIT signals |
| | [see trap(1)]. |
| | |
| | The standard input of all asynchronously processed com- |
| | mands is redirected by the shell to the null file |
| | /dev/null. You can also redirect it to a different file, |
| | for example by including < file on the command line. |
|_________|___________________________________________________________|
| && | Causes the shell to execute the next command only if the |
| (ANDIF) | preceding command has returned a zero (successful) exit |
| | status. |
|_________|___________________________________________________________|
| || | Causes the shell to execute the next command only if the |
| (ORIF) | preceding command returned a non-zero (unsuccessful) exit|
| | status. |
|_________|___________________________________________________________|
Precedence of command separators
The character pairs && and || have equal precedence, which is higher
than the precedence of ; and &.
Colon ; and ampersand & have equal precedence.
Example:
command1&command2||command3;command4 CR
Page 17 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The shell runs command1 in the background and immediately
processes command2. If command2 returns an exit status of 0, the
shell then executes command4.
If command2 returns a non-zero exit status, command3 and command4
are then executed one after the other.
The || link overrides & and ;.
Exit status of a command list
The exit status of a command list is the exit status of the last com-
mand executed.
Command grouping
Parentheses and braces can both be used to group a number of commands.
This mechanism allows you to
- run a group of commands in the background in a fixed sequence
- collect the output of all the commands in one file or pipe it to
another command.
______________________________________________________________________
(commandlist)
______________________________________________________________________
commandlist
List of commands or pipelines separated by command separators.
The shell starts a subshell, which executes commandlist and then
exits. The original shell returns, with the same shell variables
and working directory as before.
If you redirect the standard output to a file outside the parentheses,
the output of all commands/pipelines in the list is combined and
sequentially written to the specified file. This also applies if the
standard error output is redirected to a file.
If you put a pipe symbol | after the right parenthesis, the output of
all commands in the list is passed as input to the command that fol-
lows the pipe.
If you put an ampersand & after the right parenthesis, a subshell is
started in the background. This subshell sequentially executes all
commands in the command list.
Page 18 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Example:
$ pwd;(cd /dev;pwd);pwd
/home/rose
/dev
/home/rose
In the above example, the invoked subshell makes a directory
change to /dev. However, this change in the current directory has
no influence on the parent shell.
Exit status
The exit status is the value returned by the last command executed in
commandlist.
______________________________________________________________________
{ commandlist;}
______________________________________________________________________
commandlist
List of commands or pipelines separated by command separators.
The current shell executes commandlist. The braces are shell key-
words and thus must each be preceded by a command separator and
followed by an argument separator.
In the following cases, however, commandlist is executed in a subshell
despite the braces, i.e. the braces have the same effect as
parentheses:
- If you redirect the standard output to a file outside the braces.
In this case the output of all commands in the list is combined and
sequentially written to the specified file.
This also applies if the standard error output is redirected to a
file.
- If you put a pipe symbol | after the right brace.
In this case the output of all commands in the list is passed as
input to the command that follows the pipe.
- If you put an ampersand & after the right brace.
A subshell is started in the background and sequentially executes
all commands in the command list.
Page 19 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Examples
Example 1
If no .profile file exists, a message to that effect is to be
displayed and the current shell is to exit:
[ -f .profile ] || {
echo No .profile created
exit 1
}
As the commands within the braces are executed by the current shell,
exit terminates the current shell. The || separator ensures that the
list in the braces is only executed if the Bourne shell built-in
test(1) returns a non-zero exit status.
Example 2
If the standard output of the command list is redirected to a file,
the command list is executed in a subshell in spite of the braces, as
if it were in parentheses:
$ pwd;{ cd /dev; echo Terminals:; ls tty*;} > $HOME/output
/usr1/rose
$ pwd
/usr1/rose
$ cat output
Terminals:
tty000
tty001
tty003
tty010
The current working directory does not change, because the command
list is executed in a subshell. The shell combines the output of the
echo and ls commands and writes it to the file $HOME/output.
Exit status
The exit status of the commandlist is that of the last command exe-
cuted.
BOURNE SHELL BUILT-INS
Some commands are executed by the shell itself and hence do not
require a new process to be started. Such commands are known as
built-in commands of the Bourne shell (or Bourne shell built-ins) and
differ from the other external commands in the following respects:
- They constitute subroutines of the binary file /bin/sh and thus
have predefined names which cannot be changed. You can change the
access permissions for /bin/sh, but not for the shell's individual
built-in commands.
Page 20 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- The shell's built-in commands are given precedence over external
commands (see COMMAND LINE PROCESSING below). If there is an exter-
nal command with the same name as a shell built-in, the shell
always executes the built-in unless you call the external command
by its absolute path name (e.g. /bin/pwd).
- The built-in commands are faster because the shell executes them
itself.
There are no external equivalents to most of the Bourne shell built-
ins. In fact, it is not even possible to have one for the built-in
command cd: if a new process were to be created to execute cd, the
current working directory would change only for the duration of that
process. On completion of the command, the process would also be com-
pleted; the calling shell would return, and no change of directory
would have taken place.
The output format of Bourne shell built-ins is not standardized, so
you should not rely on a particular output format when using them in
programs or shell scripts.
Since most of the built-in commands of the Bourne shell are described
in the normal alphabetical sequence (see SEE ALSO below) along with
the external commands, they are simply listed briefly here:
______________________________________________________________________
| Bourne shell | Function | External equiv- |
| built-in | | alent |
|______________|___________________________________|__________________|
| bg | move a job into the background | |
|______________|___________________________________|__________________|
| break | exit from the enclosing loop | |
|______________|___________________________________|__________________|
| cd | change working directory | |
|______________|___________________________________|__________________|
| chdir | change working directory | |
|______________|___________________________________|__________________|
| continue | resume execution at the next | |
| | iteration of the enclosing loop | |
|______________|___________________________________|__________________|
| echo | echo command-line arguments | /bin/echo |
|______________|___________________________________|__________________|
Page 21 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
______________________________________________________________________
| Bourne shell | Function | External equiv- |
| built-in | | alent |
|______________|___________________________________|__________________|
| eval | evaluate command-line arguments | |
| | and execute as command | |
|______________|___________________________________|__________________|
| exec | overlay current shell | |
|______________|___________________________________|__________________|
| exit | terminate shell script | |
|______________|___________________________________|__________________|
| export | export shell variables | |
|______________|___________________________________|__________________|
| fg | move job into the foreground | |
|______________|___________________________________|__________________|
| getopts | check arguments for legal options| /bin/getopts |
|______________|___________________________________|__________________|
| hash | process shell hash table | |
|______________|___________________________________|__________________|
| jobs | list information about a job | |
|______________|___________________________________|__________________|
| kill | send/list signals | /bin/kill |
|______________|___________________________________|__________________|
| newgrp | change to new group | /bin/newgrp |
|______________|___________________________________|__________________|
| pwd | print working directory | /bin/pwd |
|______________|___________________________________|__________________|
| read | read arguments from standard | |
| | input and assign to shell vari- | |
| | ables | |
|______________|___________________________________|__________________|
| readonly | protect shell variables | |
|______________|___________________________________|__________________|
| return | causes a shell function to return| |
| | to the invoking script | |
|______________|___________________________________|__________________|
| set | set shell options or positional | /bin/sh |
| | parameters | |
|______________|___________________________________|__________________|
| shift | shift values of positional param-| |
| | eters to left | |
|______________|___________________________________|__________________|
| stop | stop PID sends a signal (= kill | |
| | -23 PID) | |
|______________|___________________________________|__________________|
Page 22 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
______________________________________________________________________
| Bourne shell | Function | External equiv- |
| built-in | | alent |
|______________|___________________________________|__________________|
| suspend | send a signal by a user (= kill | |
| | -24 or CTRL-Z) | |
|______________|___________________________________|__________________|
| test | test conditions | /bin/test |
|______________|___________________________________|__________________|
| times | print accumulated times for | |
| | processes run from the shell | |
|______________|___________________________________|__________________|
| trap | define signal handling | |
|______________|___________________________________|__________________|
| type | display type of command | |
|______________|___________________________________|__________________|
| ulimit | set or display user file size | |
| | limits | |
|______________|___________________________________|__________________|
| umask | set file-creation mode mask | |
|______________|___________________________________|__________________|
| unset | delete shell variables/shell | |
| | functions from the environment | |
|______________|___________________________________|__________________|
| wait | wait for background processes to | |
| | terminate | |
|______________|___________________________________|__________________|
| : | return exit status 0, see | /bin/true |
| | colon(1) | |
|______________|___________________________________|__________________|
| . | execute shell scripts in the | |
| | current shell, see dot(1) | |
|______________|___________________________________|__________________|
| [ | test conditions, see test(1) | |
|______________|___________________________________|__________________|
Page 23 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
SHELL METANOTATIONS
This section contains a list of characters and character combinations
that have a special meaning for the shell. The table below briefly
indicates the special meaning of each metacharacter and gives a refer-
ence to the section in which it is discussed in detail [see also
specialchar(5)].
The metacharacters contained in a command line are evaluated by the
shell in several steps (see COMMAND LINE PROCESSING below).
________________________________________________________________________
| Metacharacter | Meaning | Described in |
|_________________|______________________________|______________________|
| blank | argument separator | Entering and group- |
| newline | | ing commands |
| tab | | |
|_________________|______________________________|______________________|
| newline | end of command | Command lists |
| | | or | |
| ; | command separator | |
| & | | |
| || | | |
| && | | |
|_________________|______________________________|______________________|
| (commandlist) | grouping of commands | Command grouping |
| { commandlist;} | | |
|_________________|______________________________|______________________|
| `command` | replace by output | Command substitution|
|_________________|______________________________|______________________|
| * | replace with any matching | File name generation|
| ? | file names | |
| [s] | | |
| [c1-c2] | | |
| [!s] | | |
| [!c1-c2] | | |
|_________________|______________________________|______________________|
| >file | redirect standard output | Command input and |
| >>file | | output redirection |
| >&number | close standard output | |
| >&- | | |
|_________________|______________________________|______________________|
| <file | redirect standard input | Command input and |
| <<argument | | output redirection |
| <<-argument | | |
| <&number | close standard input | |
| <&- | | |
|_________________|______________________________|______________________|
Page 24 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
________________________________________________________________________
| Metacharacter | Meaning | Described in |
|_________________|______________________________|______________________|
| name=value | assign value | Shell variables |
|_________________|______________________________|______________________|
| $name | access value of variable | Shell parameters |
| ${name} | | |
|_________________|______________________________|______________________|
| ${name-value} | replace on condition that | Defining default |
| ${name?value} | variable is defined | values for shell |
| ${name+value} | | parameters |
|_________________|______________________________|______________________|
| ${name=value} | assign if variable is not | Defining default |
| | defined | values for shell |
| | | parameters |
| ${name:=value} | assign if variable is not | |
| | defined or is set to the | |
| | null string | |
|_________________|______________________________|______________________|
| ${name:-value} | replace on condition that | Defining default |
| ${name:?value} | variable is defined and is | values for shell |
| ${name:+value} | not set to the null string | parameters |
|_________________|______________________________|______________________|
| $0 | 1st command-line argument | Shell parameters |
| $1, $2, ... , $9| positional parameters | |
| $* | all command-line arguments | |
| "$*" | as $* but as one argument | |
| $@ | all command-line arguments | |
| "$@" | as $@ but as $# arguments | |
| $# | number of command-line argu-| |
| | ments | |
|_________________|______________________________|______________________|
| $$ | read-only shell parameters | Shell parameters |
| $! | | |
| $? | | |
| $- | | |
|_________________|______________________________|______________________|
| name() | shell function | Shell functions |
| { commandlist;} | | |
|_________________|______________________________|______________________|
| \ | escape characters | Quoting shell meta- |
| '...' | | characters |
| "..." | | |
|_________________|______________________________|______________________|
| # | comment character | Comments in shell |
| ;; | command list terminator in | scripts |
| | case constructs | |
|_________________|______________________________|______________________|
Page 25 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Quoting shell metacharacters
Every shell metacharacter can be escaped, i.e. made to represent
itself. Depending on the character you wish to escape (or quote), one
of the escape characters described below can be used.
The escape characters themselves do not form part of the command-line
arguments. The shell strips these characters before passing the argu-
ments on to the command.
Escape characters
\ Escapes the special meaning of the next character. The backslash
\ can be used to escape all shell metacharacters.
\ CR causes the shell to ignore the special meaning of the new-
line as an argument or command separator. The shell ignores this
entry and strips both the backslash and the newline character
from the command line.
'string'
Escapes the special meaning of all characters in string. Single
quotes can be used to escape all shell metacharacters with the
exception of a single quote itself.
Since blanks, tabs and newline characters enclosed within single
quotes lose their special meaning as argument separators, the
shell treats the entire string as a single argument.
"string"
Only the following characters retain their special meaning for
the shell:
$ when followed by a variable name is replaced by the value of
the shell variable.
'command'
is replaced by the output of command (see COMMAND SUBSTITU-
TION below).
\ escapes the special meaning of the metacharacter following
it.
Page 26 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Only the characters $, ` ...` , and \ retain their special
meaning within double quotes. If none of these metacharac-
ters follows the backslash, the backslash is treated as a
character that is part of the string.
All other metacharacters within the double quotes are treated as
being escaped.
Since blanks, tabs and newline characters enclosed within double
quotes lose their special meaning as argument separators, the
shell treats the entire string as a single argument. There is,
however, an exception here: "$@" is the same as "$1" "$2" ...
"$9", i.e. the individual command-line arguments are retained as
separate arguments.
Effect of single and double quotes (and backquotes)
_____________________________________________________________________
| escape| argument| command| \ | $ | * | ? | [ | ` | " | ' |
|_______|__________________|_____|____|____|____|_____|____|____|____|
| | separator | | | | | | | | |
|_______|_________|________|_____|____|____|____|_____|____|____|____|
| '...' | yes | yes | yes | yes| yes| yes| yes | yes| yes| e |
|_______|_________|________|_____|____|____|____|_____|____|____|____|
| "..." | yes | yes | no | no | yes| yes| yes | no | e | yes|
|_______|_________|________|_____|____|____|____|_____|____|____|____|
| `...` | yes | yes | yes | no | no | no | no | e | no | no |
|_______|_________|________|_____|____|____|____|_____|____|____|____|
e stands for end of quoted string
SHELL VARIABLES
Shell variables are always of the type string. They do not need to be
declared; they are held to be defined as soon as you assign a value to
them.
Shell variables are useful when you wish to store strings that are
frequently used. Storage space requirements are taken care of by the
shell itself.
In the following section you will learn
- how to define and assign a value to a variable
- how to access the value of the variable
- the standard variables used by the shell.
Page 27 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Defining shell variables
Every shell variable consists of a name and a value and is defined as
follows:
______________________________________________________________________
name=value [name=value] ...
______________________________________________________________________
name Name of the variable. A variable name must begin with a letter or
an underscore (_). The first character may be followed by
letters, digits, and underscores in any order.
A shell variable and a shell function cannot be given the same
name in the current shell.
If a variable with the specified name has already been defined,
the new assignment causes its original value to be forgotten in
the current shell.
= The assignment operator. There should be no blanks between name
and value.
value
Value of the variable.
If value contains blanks, tabs, or newline characters, they must
be escaped. The shell assigns the characters *, $, and [...] to
the name variable without interpreting them. value is thus not
replaced by all matching file names (see FILE NAME GENERATION
below).
If you omit value or specify "" or '' for it, the null string
will be assigned to name.
The assignment can either be made interactively or included in a shell
script. You can also write several assignments on one line, separated
by the usual argument separators.
Variables defined in this way are by default only known in the current
shell. The Bourne shell built-in export(1) must be used if they are
also to be recognized in every subshell. Variables can be exported
down to subshells but not up to parent shells. See THE ENVIRONMENT
below for further details.
The Bourne shell built-in read(1) can also be used to define shell
variables.
The Bourne shell built-in unset(1) removes the definition of a shell
variable.
Page 28 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Accessing the value of a variable
The Bourne shell built-in set(1) lists all variables defined in the
current shell along with their values. You can, however, also directly
access the value of a variable as follows:
______________________________________________________________________
$name
______________________________________________________________________
name Name of the shell variable whose value you want to access. The
name must come immediately after the dollar sign without inter-
vening space.
name is a shell variable, while $name represents a keyword parameter.
You can assign a value to a variable, but not to a keyword parameter
(see also SHELL PARAMETERS below).
Example:
To find out the value of the HOME variable, you enter:
$ echo $HOME
The Bourne shell built-in echo(1) writes the value of the HOME
variable on standard output.
Standard shell variables
Some standard variables are automatically passed to the login shell
when it is started. Before displaying its first prompt, this shell
defines a few additional standard variables itself.
Most standard variables are assigned a default value, which is also
known in every subshell. It is not necessary to export the values of
standard variables to subshells unless you change them from the
default. Otherwise the default values automatically apply in every
subshell.
If you wish to define shell variables permanently, you can enter the
appropriate assignments in your $HOME/.profile file. This file is exe-
cuted by the login shell before it issues its prompt.
Page 29 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The following standard variables are recognized by the shell:
______________________________________________________________________
CDPATH=directory[:directory ...]
______________________________________________________________________
The path names of directories to be searched by the cd command can be
assigned to the CDPATH variable. The individual path names must be
separated from one another by a colon. You can identify the current
directory by entering a dot (.) or the null string. A colon immedi-
ately after the assignment operator assigns the working directory as
the first directory in the list.
The Bourne shell built-in cd(1) accesses CDPATH when searching for the
directory that is to be made the working directory. The search begins
in the directory whose path name precedes the first colon. All path
names contained in the CDPATH variable are processed from left to
right [see cd(1)].
Default value: none, i.e. by default CDPATH is undefined.
If CDPATH is undefined, cd looks for relative path names relative to
the current working directory.
______________________________________________________________________
HOME=directory
______________________________________________________________________
The HOME variable is assigned the absolute path name of the home
directory. If you invoke the Bourne shell built-in cd(1) without argu-
ments, cd accesses HOME, and the home directory becomes the new work-
ing directory.
The login shell looks for the .profile file in the directory assigned
to the HOME variable.
Default value: The login command assigns the absolute path name of
your login directory as the value of the HOME variable. This path name
is allocated to your login name in the /etc/passwd file.
______________________________________________________________________
IFS=c...
______________________________________________________________________
The values of the IFS variable are argument separators, where c is any
single character. Blanks, tabs, and newline characters have to be
escaped. A list of characters has to be entered without intervening
blanks.
Page 30 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The shell evaluates the content of the IFS variable in the following
cases:
- when the Bourne shell built-in read(1) parses an input line into
arguments
- when the shell does its second parse run on the command line (see
COMMAND LINE PROCESSING below, Step 8).
The IFS variable cannot be removed from the environment with unset(1).
Default value: blank tab newline. The login shell assigns this value
to IFS.
If you modify the value of the IFS variable, read and the shell on its
second parse run will only understand the modified argument separa-
tors.
______________________________________________________________________
LANG=language
______________________________________________________________________
The NLS variable LANG is used to define an internationalized shell
environment. The value of LANG is the name of an existing database.
These databases reside in the directory /usr/lib/locale. If the LCALL
variable is not set, LANG defines not only the native language but
also everything that can be defined individually in an international-
ized program with the NLS variables LCCOLLATE, LCCTYPE, LCMONETARY,
LCNUMERIC, LCTIME and LCMESSAGES.
If LANG is undefined or null or has an invalid value, the system acts
as if it were not internationalized.
______________________________________________________________________
LCALL=language
______________________________________________________________________
The value of LCALL overrides all LC* variables and LANG.
______________________________________________________________________
LCCOLLATE=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCCOLLATE defines
the collating sequence for ordering strings of characters.
Page 31 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If LCCOLLATE is undefined or is assigned the null string, its value
defaults to the value of LANG. If LCCOLLATE has an invalid value, an
internationalized program will act as if it were not international-
ized.
______________________________________________________________________
LCCTYPE=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCTYPE defines
which character class each character belongs to, and how uppercase
letters are converted to lowercase and vice versa.
If LCTYPE is undefined or is assigned the null string, its value
defaults to the value of LANG. If LCTYPE has an invalid value, an
internationalized program will act as if it were not internationalized.
______________________________________________________________________
LCMESSAGES=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCMESSAGES
defines the language in which messages are displayed by an interna-
tionalized program. If LCMESSAGES has an invalid value, an interna-
tionalized program will act as if it were not internationalized.
______________________________________________________________________
LCMONETARY=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCMONETARY
governs currency symbols and monetary value formats.
If LCMONETARY is undefined or is assigned the null string, its value
defaults to the value of LANG. If LCMONETARY has an invalid value, an
internationalized program will act as if it were not internationalized.
______________________________________________________________________
LCNUMERIC=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCNUMERIC defines
the radix character (decimal point), the exponentiation symbol and the
thousands separator.
If LCNUMERIC is undefined or is assigned the null string, its value
defaults to the value of LANG. If LCNUMERIC has an invalid value, an
internationalized program will act as if it were not internationalized.
Page 32 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
______________________________________________________________________
LCTIME=language
______________________________________________________________________
If the LCALL variable is not set, the NLS variable LCTIME defines
the format for date and time strings.
If LCTIME is undefined or is assigned the null string, its value
defaults to the value of LANG. If LCTIME has an invalid value, an
internationalized program will act as if it were not internationalized.
______________________________________________________________________
LOGNAME=loginname
______________________________________________________________________
The login command assigns the LOGNAME variable the name under which
you logged in on the system.
______________________________________________________________________
MAIL=file
______________________________________________________________________
The MAIL variable is assigned the absolute path name of the file to
which mail writes incoming mail.
If the MAILPATH variable has not been defined, the shell informs you
when new mail messages arrive in this file by issuing the message:
you have mail
Default value: /var/mail/$USER. The login command assigns this value
to MAIL.
______________________________________________________________________
MAILCHECK=integer
______________________________________________________________________
The MAILCHECK variable is assigned an integer value. The shell
accesses the MAILCHECK variable: every integer seconds it checks
whether mail messages have arrived in your $MAIL file or in any of the
files whose path names are assigned to the MAILPATH variable.
If you assign MAILCHECK a value of 0, the shell inspects your mail
files whenever it is about to issue its prompt.
Page 33 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The following message is issued if mail has arrived: you have mail
The MAILCHECK variable cannot be removed from the environment with
unset.
Default value: 600, i.e. the shell checks every 10 minutes (600
seconds) whether new mail has arrived in any of the files whose path
names have been assigned to the MAIL or MAILPATH variables.
The login shell assigns this value to MAILCHECK.
______________________________________________________________________
MAILPATH=file[%text][:file[%text]]...
______________________________________________________________________
This variable can be used to specify the path names of files to be
checked for new mail. The individual path names must be separated by a
colon and represent files for which you have read permission.
In addition, each path name can be followed with a % sign and a text
which is to be output by the shell when new mail arrives in the
corresponding file.
The shell accesses the MAILPATH variable to determine whether new mail
has arrived in any of the files specified in this variable.
Default value: none, i.e. by default MAILPATH is undefined.
______________________________________________________________________
PATH=directory[:directory]...
______________________________________________________________________
The PATH variable is assigned the absolute path names of the direc-
tories in which the shell is to look for commands. A colon is used to
separate the individual path names.
You can identify the working directory by entering a dot (.) or the
null string, i.e. nothing.
For security reasons, the current working directory should always come
last in the list of directories assigned to the PATH variable.
The shell accesses the PATH variable when searching for commands
invoked under their file basenames, i.e. a name not including any
slashes. The search begins in the directory whose path name precedes
the first colon. All path names assigned to the PATH variable are pro-
cessed from left to right until the shell finds the required file or
establishes that the file does not appear in any of the listed direc-
tories.
Page 34 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The PATH variable cannot be removed from the environment with unset.
PATH has different default settings for the superuser and for non-
privileged users. The appropriate value is derived from the entries in
/etc/default/login.
The login shell assigns this default value to PATH.
______________________________________________________________________
PS1=promptstring
______________________________________________________________________
The PS1 variable is assigned the prompt string that the shell is to
issue when it is ready to accept input. Any blanks or tabs appearing
in promptstring have to be escaped.
The PS1 variable cannot be removed from the environment with unset.
Default value: $
The login shell assigns this default value to PS1.
______________________________________________________________________
PS2=promptstring
______________________________________________________________________
The PS2 variable is assigned the promptstring that the shell is to
issue when it expects further input after a newline character or when
you have escaped a newline character. Any blanks or tabs appearing in
promptstring have to be escaped.
The PS2 variable cannot be removed from the environment with unset.
Default value: >
The login shell assigns this default value to PS2.
______________________________________________________________________
SHELL=commandinterpreter
______________________________________________________________________
The SHELL variable is assigned the absolute path name of the command
interpreter. Whenever a subshell is invoked, the calling shell looks
to see if the value of SHELL contains the letter r. If it does, the
called subshell is a restricted shell.
The editors ed and vi access the SHELL variable if you escape to the
shell or invoke a shell command while working with them.
Page 35 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Default value: The login command assigns this variable the absolute
path name of the program that the system runs for you when you log in.
The path name of this startup file is allocated to your login name in
the /etc/passwd file and is /bin/sh by default.
______________________________________________________________________
TERM=type
______________________________________________________________________
The special process getty assigns the type of the terminal to the TERM
variable. type is the corresponding entry in the file /etc/gettytab.
Editors access the TERM variable to find out the capabilities of the
terminal.
______________________________________________________________________
TZ=stdoffset1[dst[offset2][;start[/time],end[/time]]] Format 1
TZ=stdoffset1[dst[offset2][;start[/time],end[/time]]] Format 2
TZ=:zonename Format 3
______________________________________________________________________
The TZ variable contains timezone information. The date command and
most of the library functions which reference the time of day use TZ
to determine the timezone and to convert universal time UTC (Universal
Time Coordinated) to local time and vice versa.
The individual components of the value of TZ follow one another
without intervening blanks, e.g. MET-1 (Format 1 or 2) or :US/Pacific
(Format 3). The meaning of each component is as follows:
Format 1:
std Standard local timezone. std consists of at least three letters,
either uppercase or lowercase.
Note: std is not used in calculating the local time (this being
the job of offset1). std simply defines the name of the
timezone.
offset1
Indicates the value that must be added to the local time in order
to arrive at Coordinated Universal Time (UTC, also known as
Greenwich Mean Time, or GMT).
Page 36 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
offset1 has the following format:
[+]hh[:mm[:ss]]
+ If the specified time is preceded by a plus sign, the
timezone is west of the Prime Meridian. If it is preceded by
a minus sign, the timezone is east of the Prime Meridian.
+ not specified:
Defaults to +.
hh Hours (0-24)
mm Minutes (0-59)
ss Seconds (0-59)
Example:
Central European time (MET) is equal to UTC + 1 hour:
MET=UTC+1, so UTC=MET-1. In this case offset1 would be -1.
dst Summer timezone (daylight saving time; same format as std). As
with std, dst simply defines the name of the summer timezone.
dst not specified:
Conversion to summer time does not apply.
offset2
Indicates the value that must be added to the local summer time
in order to arrive at Coordinated Universal Time (UTC).
offset2 has the same format as offset1.
offset2 not specified:
summer time = standard time + 1 hour
start[/time],end[/time]
start[/time] defines when to change from standard time to summer
time; end[/time] specifies when to change back. start and end
specify the day on which the change is made; time indicates when
this happens (in current local time).
start and end are given in the form of a number n (0 <= n <= 365),
meaning the nth day of the Julian calendar. Leap days are counted,
so in this format it is possible to refer to February 29.
time has the format: hh[:mm[:ss]]
(see offset1)
Page 37 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
time not specified:
time = 02:00:00
start[/time],end[/time] not specified:
In Central Europe, the change from standard time to summer time
occurs on the last Sunday in March; in the USA and Canada on the
second Sunday in April. Summer time is changed back to standard
time on the last Sunday in October (at 02:00:00 in both cases).
Format 2:
Format 2 is like Format 1 with the addition of more flexible syntax
for specifying when summer time starts and ends. Note that the only
difference in the syntax synopsis is that Format 2 has a comma instead
of a semicolon before start[/time],end[/time].
std See Format 1
offset1 See Format 1
dst See Format 1
offset2 See Format 1
start[/time],end[/time]
start[/time] defines when to change from standard time to
summer time; end[/time] specifies when to change back. start
and end specify the day on which the change is made; time
indicates when this happens (in current local time).
start and end can have any of the following formats:
Jn stands for the nth day of the Julian calendar, where 1
<= n <= 365. Leap days are not counted. In other words,
February 28 is always day 59, and March 1 is always day
60. It is impossible to refer to February 29 in this
format.
n stands for the nth day of the zero-based Julian calen-
dar, where 0 <= n <= 365. Leap days are counted, and it
is possible to refer to February 29.
Mm.w.d
stands for the dth day of week w of month m (0 <= d <=
6, 1 <= w <= 5, 1 <= m <= 12).
Page 38 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Day zero of a week is Sunday. Week 1 of a month is the
week in which the first day of the month falls. When a
value of 5 is specified for a week (Mm.5.d), the "last
d-day in month m" is implied. For example, M9.5.6 refers
to the last Saturday in September.
time has the format: hh[:mm[:ss]]
(see offset1)
time not specified:
time = 02:00:00
start[/time],end[/time] not specified:
In Central Europe, the change from standard time to summer
time occurs on the last Sunday in March; in the USA and
Canada on the second Sunday in April. Summer time is changed
back to standard time on the last Sunday in October (at
02:00:00 in both cases).
Example:
In Central Europe, the clocks go forward on the last
Sunday in March, and back again on the last Sunday in
October, in both cases at 2 a.m. Thus the appropriate
setting for the TZ variable is:
TZ=MET-1MDT,M3.5.0/02:00:00,M9.5.0/02:00:00
Format 3:
zonename
zonename is the name of a predefined timezone with a predefined
change to summer time.
The accepted values for zonename are the names of the files under
/usr/lib/locale/TZ. These files are created with the system
administration command zic(1M).
Examples:
In /usr/lib/locale/TZ there are files called GMT and Greenwich-1
and a directory US including files called Pacific and Yukon.
$ TZ=:GMT date
Wed Oct 23 15:18:47 GMT 1991
$ TZ=Greenwich-1 date
Wed Oct 23 14:18:47 GMT-1 1991
$ TZ=:US/Pacific date
Wed Oct 23 08:18:47 PDT 1991
Page 39 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Note: Syntax errors in an environment variable such as TZ are not
allowed to cause a command like date to abort; they have to
trigger a default response instead. The appropriate default
response for the environment variable TZ is as follows:
If std or offset1 is unidentifiable (Format 1 or 2), or if the
named file does not exist under /usr/lib/locale/TZ (Format 3),
the clock reverts to GMT.
In other cases, only the valid part of the variable is inter-
preted, and the rest is ignored.
Examples:
$ TZ=invalid date
Wed Oct 23 15:27:02 GMT 1991
$ TZ=MET-1MDT,andthisistherest
Wed Oct 23 16:27:02 MET 1991
______________________________________________________________________
USER=loginname
______________________________________________________________________
The login command assigns the USER variable the name under which you
logged in on the system. The USER variable has only been retained for
compatibility with earlier versions; it has now been replaced by the
LOGNAME variable, which serves the same purpose.
THE ENVIRONMENT
Whenever a process, including the shell, is started, it is provided
with a range of information by the calling process. This includes:
- information that is essential for the execution of the process,
i.e. information on parent and child processes, open files, the
current directory, defined signal handling, etc.
- information on specific variables and the values assigned to them.
This information all forms part of the process environment. While a
process is executing it may add further local variables to its
environment or make local changes to the values of existing variables.
In the following section we explain:
- which variables the shell passes to the initial environment of a
command (see Initial environment for a command below)
- how to modify the environment of the current shell (see Runtime
environment of the current shell below).
Page 40 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Initial environment for a command
When you invoke a command, the shell passes to this command:
- the names and values of all shell variables that you have exported
in the current shell or in a parent shell and have not removed from
the environment with the unset command, and
- any standard variables whose values you have not changed or removed
with unset. The standard variables IFS, MAILCHECK, PATH, PS1 and
PS2 cannot be removed in any case.
These variables and their values represent the initial environment
that is inherited by the invoked command from the shell that calls it.
Use the env command if you wish to check which variables are passed by
the current shell to each invoked command.
Augmenting the initial environment for a command
When you invoke a command, you can augment its environment without
affecting the environment of the current shell or the initial environ-
ment of other programs executed by the shell. You do this by writing
the appropriate assignments on the command line before the command
name.
These assignments are not carried out in the current shell, but in the
process that the shell starts in order to execute this command. The
assigned variables are added to the environment of the command, and
the command is therefore able to access them; but they are not avail-
able in the the current shell.
If the -k option is set in the current shell [see set(1)], such
assignments can be written at any position within the command line.
Variables thus defined are known only to the command invoked on that
line.
Example:
The following two command lines lead to the same result:
customer=mason script
(customer=mason;export customer;script)
The first line contains an assignment before the command name.
This assignment is not carried out in the current shell, but in
the subshell that runs script. The customer variable is then
passed to the script as part of its environment. On completion of
the script, the subshell terminates, so the customer variable
will not be known in the parent shell.
Page 41 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The second line is enclosed within parentheses, which means that
all parenthesized commands are to be executed in a subshell. The
subshell adds the customer variable to the environment for script
and passes this environment, including the customer variable, to
the script. The subshell terminates on reaching the end of the
script, so the customer variable will not be known in the parent
shell.
If you define variables in the current shell and export them using
export, you modify both the environment of the current shell and the
initial environment of any commands that are invoked subsequently (see
next section).
Runtime environment of the current shell
When a shell is invoked, it first scans the environment that is passed
to it with the call. For each variable pair it finds, it creates a
shell parameter with the specified name and associated value.
The login shell started by login inherits its initial environment from
login. The login shell itself initializes the variables IFS,
MAILCHECK, PATH, PS1 and PS2.
Every variable that you define or redefine in a shell is added as a
local variable to the runtime environment of this shell. Local vari-
ables do not affect the environment of the command that starts the
shell, however. You can verify this with the env(1) command.
The Bourne shell built-in set(1) prints all variables defined in the
current shell, including all locally applicable variables.
You can change the runtime environment of the current shell together
with the initial environment of all commands invoked subsequently:
- The initial environment for commands can be augmented with the aid
of the Bourne shell built-in export(1). Exported shell variables
are added to the initial environment and are known to the current
shell, all its subshells, and any commands that it invokes.
- A variable can be removed from the initial environment with the aid
of the Bourne shell built-in unset(1). The exceptions to this are
the standard variables IFS, MAILCHECK, PATH, PS1 and PS2, which
cannot be removed.
A deleted variable is also no longer available in the runtime
environment of the current shell.
If the -a option is set in the current environment, all shell vari-
ables that you define or redefine are exported automatically [see
set(1)].
Page 42 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
It is also possible to modify the initial environment for a single
command (see Augmenting the initial environment for a command above).
In this case the shell's runtime environment does not change.
SHELL PARAMETERS
Shell parameters are prefixed by a dollar sign ($). The shell replaces
a parameter on the command line with the value currently assigned to
the corresponding shell variable. Shell parameters are addressed as
follows:
______________________________________________________________________
$parameter
______________________________________________________________________
parameter
Name of a shell variable or any of the following characters:
0 1 2 3 4 5 6 7 8 9 * @ # - ? $ !
If the name of a shell parameter is followed by a letter, digit or
underscore, the shell interprets this character as part of the name,
so the name has to be kept separate from any characters that follow
it. One way of doing this is to put the name in curly braces:
______________________________________________________________________
${parameter}
______________________________________________________________________
Example:
$ file=/usr1/rose/tables/list1
$ mv $file ${file}00
Omitting the braces causes the shell to search for a variable
named file00, which may well be undefined.
There are three types of parameter:
- keyword parameters,
- positional parameters and
- special shell parameters.
Page 43 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Keyword parameters
Keyword parameters are parameters in the form $name or ${name}. The
shell replaces a keyword parameter with the value of the corresponding
shell variable. If this variable is not defined, the shell substitutes
the null string for the keyword parameter.
You can create new keyword parameters or modify the value of old ones
by defining or redefining the corresponding shell variable. You do
this with the following assignment:
name=value
Here name is a shell variable, while $name is a shell parameter.
Whereas a variable can be assigned a value, a shell parameter cannot
(see the sections SHELL VARIABLES and THE ENVIRONMENT above).
Keyword parameters may be passed to every invoked subshell by includ-
ing the corresponding variable in the environment with the shell
built-in export(1).
Positional parameters
Positional parameters are the parameters $1, $2, $3, $4, $5, $6, $7,
$8 and $9. The following command-line arguments are substituted for
these positional parameters by the shell:
$1 first command-line argument
.
.
.
$9 ninth command-line argument
You can thus access the first nine command-line arguments directly,
and use $* or $@ to access all the command-line arguments collec-
tively. By using the Bourne shell built-in shift(1), you can access
the tenth and subsequent arguments directly as well.
In an interactive shell, the only way to assign values to all posi-
tional parameters at once is indirectly, with the Bourne shell built-
in set(1). Following the invocation of set, these values may also be
accessed in the current shell.
The sh -s command can be used to indirectly assign values to all posi-
tional parameters in the invoked subshell at once.
Unlike keyword parameters, positional parameters cannot be directly
redefined, and their values cannot be exported to the environment by
export.
Page 44 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Special shell parameters
The special shell parameters and their values:
$0 Invocation name of the command or the shell script; with shell
functions, $0 is the name of the current shell or the name of the
shell script, depending on where you called the function.
$* All command-line arguments, i.e. positional parameters $1 through
$9 plus any other command-line arguments.
"$*" all command-line arguments as one argument, i.e.
"$1 ... $9 ..."
$@ All command-line arguments, i.e. positional parameters $1 through
$9 plus any other command-line arguments.
"$@" all command-line arguments as separate arguments, i.e.
"$1" ... "$9" ...
$# The total number of command-line arguments; this value may be
greater than 9.
$- All options that have been set in the current shell.
$? The exit status of the last executed command; this value does not
apply to background commands.
$$ The process ID (PID) of the current shell
$! the process ID (PID) of the last command started in the back-
ground.
These values are assigned by the shell automatically. The parameters
$*, $@ and $# are modified when you assign new values to positional
parameters by using the set or sh -s command or when you use shift.
Substituting values for shell parameters
In processing the command line the shell substitutes values for the
shell parameters on the command line (see COMMAND LINE PROCESSING,
Step 4). The value of a shell parameter can be accessed as follows:
$parameter or ${parameter}
If no value has been defined, the shell replaces the specified parame-
ter with the null string.
Page 45 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Defining default values for shell parameters
If you want to ensure that a shell parameter is always replaced by a
predefined value, you can define a default value for it. The condition
under which the shell is to substitute this default value can be
specified together with the definition.
This section describes how you can define such default values. The
value for parameter may be given as the name of a shell variable or
any of the following characters:
0 1 2 3 4 5 6 7 8 9 * @ # - ? $ !
The meanings of these characters are explained in the section on SHELL
PARAMETERS above.
Any arbitrary strings are permitted for the specified defaultvalue.
This defaultvalue is only interpreted by the shell when it replaces
the corresponding parameter with this value (see the example at the
end of this section).
The following conventions are recognized by the shell:
______________________________________________________________________
${parameter-defaultvalue}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (note that the assigned value may be the null string).
If it is, it substitutes the defined value.
If it is not, it substitutes the defaultvalue.
This is not equivalent to assigning a value to the parameter: the
defaultvalue applies for this access only.
______________________________________________________________________
${parameter:-defaultvalue}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (but not the null string; the colon precludes the null string).
If it is, it substitutes the defined value.
If it is not, it substitutes the defaultvalue.
This is not equivalent to assigning a value to the parameter: the
defaultvalue applies for this access only.
Page 46 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
______________________________________________________________________
${parameter=defaultvalue}
______________________________________________________________________
parameter must be the name of a shell variable.
The shell checks that parameter is defined, i.e. already assigned a
value (note that the assigned value may be the null string).
If it is, it substitutes the defined value.
If it is not, it assigns the defaultvalue to parameter and substi-
tutes its value.
Only shell variables can be assigned values in this way, so $parameter
cannot be a positional parameter or a special shell parameter.
______________________________________________________________________
${parameter:=defaultvalue}
______________________________________________________________________
parameter must be the name of a shell variable.
The shell checks that parameter is defined, i.e. already assigned a
value (but not the null string; the colon precludes the null string).
If it is, it substitutes the defined value.
If it is not, it assigns the defaultvalue to parameter and substi-
tutes its value.
Only shell variables can be assigned values in this way, so $parameter
cannot be a positional parameter or a special shell parameter.
______________________________________________________________________
${parameter?[defaultvalue]}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (note that the assigned value may be the null string).
If it is, it substitutes the defined value.
If the condition is not fulfilled and a defaultvalue has been speci-
fied, the shell aborts execution of the command or shell script and
writes the following error message on the standard error output:
parameter: defaultvalue
Page 47 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If the condition is not fulfilled and no defaultvalue has been speci-
fied, the shell aborts execution of the command or shell script and
writes the following error message on the standard error output:
parameter: parameter null or not set
No value is assigned to the parameter in this case.
______________________________________________________________________
${parameter:?defaultvalue}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (but not the null string; the colon precludes the null string).
If it is, it substitutes the defined value.
If the condition is not fulfilled and a defaultvalue has been speci-
fied, the shell aborts execution of the command or shell script and
writes the following error message on the standard error output:
parameter: defaultvalue
If the condition is not fulfilled and no defaultvalue has been speci-
fied, the shell aborts execution of the command or shell script and
writes the following error message on the standard error output:
parameter: parameter null or not set
No value is assigned to the parameter in this case.
______________________________________________________________________
${parameter+defaultvalue}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (note that the assigned value may be the null string).
If it is, it substitutes the defaultvalue.
If it is not, it substitutes the null string.
______________________________________________________________________
${parameter:+defaultvalue}
______________________________________________________________________
The shell checks that parameter is defined, i.e. already assigned a
value (but not the null string; the colon precludes the null string).
Page 48 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If it is, it substitutes the defaultvalue.
If it is not, it substitutes the null string.
Example:
$ echo ${dir:-`pwd`}
/usr1/carl/src
The shell executes pwd only if the variable dir is undefined or
has a value equal to the null string.
COMMAND SUBSTITUTION
In processing the command line the shell replaces a command enclosed
in backquotes `...` with the output produced by the command:
______________________________________________________________________
`command`
______________________________________________________________________
command
Name of the command which the shell is to execute; the shell
takes the output of this command and substitutes it for `command`
on the command line.
If the command line consists of `command` on its own, the shell
attempts to execute the output of command.
Processing proceeds in the following sequence:
- the current shell detects the backquotes on the command line and
calls a subshell.
- the subshell processes command (see COMMAND LINE PROCESSING below)
and terminates.
- `command` is replaced on the command line by the output of command.
- the shell parses the thus modified command line again, treating as
argument separators the characters assigned to the IFS variable.
- the current shell executes the command line.
If you have redirected the standard output within the backquotes,
`command` will be replaced by the null string.
Several commands may be entered within backquotes, separated from each
other by command separators.
Page 49 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Example:
You want the shell prompt to tell you the name of the current
host:
$ PS1="<`hostname`> "
<amadeus>
As a result of the double quotes, the blank after > forms part of
$PS1.
COMMAND INPUT AND OUTPUT REDIRECTION
By default, the standard input of a command is the keyboard, while the
standard output and standard error are both assigned to the terminal
screen. These three standard I/O files can also be referenced via the
following file descriptor values:
0 for standard input
1 for standard output
2 for standard error.
When the shell initiates a particular command in the background, it
redirects the standard input for this command to the null file
/dev/null (the bit bucket). However, you can redirect the standard
input of a background command to a different file.
The default assignments for a command may be altered by specifying the
redirection anywhere in the command. The following section explains
the various forms of redirection for:
- standard input
- standard output
- standard error.
Redirecting standard input
The less-than sign < redirects the standard input. The argument <...
does the same as 0<...
<file
Redirects the standard input of the command to file. The command
reads its input from file.
file Name of the file to which the standard input is to be
redirected. This file must already exist and must be read-
able by you.
Page 50 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Please note that since the shell has not yet interpreted the
metacharacters *, ?, and [...] at this stage, these charac-
ters should not be used when specifying file.
<&- Closes the standard input for the command. This means that the
command only receives EOF as its input.
Example:
$ wc -l <&-
0
<&digit
Redirects the standard input of the command to the file associ-
ated with file descriptor digit. The command then reads its input
from this file.
digit
File descriptor of the file to which standard input is to be
redirected.
The character & following < instructs the shell that the next
argument is a file descriptor and not a file name.
<<[-]string
Introduces a Here Document. Shell scripts use Here Documents for
commands that read from standard input.
The standard input of the command is redirected to the Here Docu-
ment, which comprises all the lines in the script between the
introductory line and the first line that contains nothing but
string. If the latter does not exist, the command reads to the
end of the script. The command reads its input from the Here
Document.
The shell processes the lines of the Here Document, replacing
variables with their value and commands in backquotes with their
output. The lines of the Here Document are passed to the command
after these substitutions have been made (see COMMAND LINE PRO-
CESSING, Step 5).
Characters such as \, $, and `...` must be quoted in the Here
Document (with a preceding backslash) if they are to be treated
literally. Quoting any character in string, for example by escap-
ing it with a backslash, causes the entire document to be treated
literally, i.e. escapes all special characters in it.
- Causes the shell to strip all leading tabs from string and
from the Here Document.
Page 51 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- not specified:
Initial tabs are retained.
string
Any string; must not appear as part of the Here Document
itself. The document ends at the first line that contains
only the specified string. If there is no such line, the end
of the script containing the document acts as the end of the
document.
Quoting any character in string, for example by escaping it
with a backslash, causes all shell metacharacters in the
Here Document to be escaped automatically.
The occurrence of string which marks the end of the Here
Document has to be written without the escape symbol.
Example of a Here Document:
The contents of the shell script post are as follows
(without the line numbers):
1 mail $* << STOP
2 To all system administrations!!
3
4 The next meeting on data security is scheduled for
5 Friday, December 13, at 10 a.m. in the conference room
6 on the 6th floor. Please make every effort to attend.
7
8 STOP
The Here Document comprises lines 2 to 7; the string STOP
terminates it. The standard input of the mail(1) command is
redirected to the document.
Redirecting standard output
The greater-than sign > redirects the standard output. The argument
>... does the same as 1>...
>file
Redirects the standard output of the command to file. The command
writes its input to file.
file Name of the file to which the standard output is to be
redirected.
If the file already exists, it previous contents are
deleted. If the file does not yet exist, it is created.
Page 52 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Please note that since the shell has not yet interpreted the
metacharacters *, ?, and [...] at this stage, these charac-
ters should not be used when specifying file.
>&- Closes the standard output for the command. The command does not
write any output.
Example:
$ ls >&-
$
>&digit
Redirects the standard output of the command to the file associ-
ated with file descriptor digit. The command then writes its
input to this file.
digit
File descriptor of the file to which standard output is to
be redirected.
The character & following > instructs the shell that the next
argument is a file descriptor and not a file name.
>>file
Redirects the standard output of the command to file. The command
writes its output to file.
file Name of the file to which the standard output is to be
redirected.
If the file already exists, the output from the command is
appended to its previous contents. Otherwise, a new file is
created.
Please note that since the shell has not yet interpreted the
metacharacters *, ?, and [...] at this stage, these charac-
ters should not be used when specifying file.
Redirecting standard error
The argument 2> redirects standard error output. The file descriptor 2
must be included.
2>file
Redirects the standard error output of the command to file. The
command writes all its error messages to file.
file See the description under >file.
Page 53 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
2>&1 Redirects standard error to the file associated with file
descriptor 1 (see description under >&digit). The error messages
and the output from the command are sequentially written to the
corresponding file.
2>>file
Redirects the standard error of the command to file. The command
writes all its error messages to file.
file See the description under >>file.
Multiple redirections
A redirection can appear at any point on the command line. You can
also include several redirections on the same command line:
- You can redirect both the standard input and the standard output
for a command. The two redirections should be to different files,
as otherwise the shell would delete the file before the command
could read its input.
Example:
$ <list sort >list
After execution of this command, the file list will be empty.
The shell redirects the standard input and the standard output
of sort before running sort itself. Because of the >list argu-
ment, the previous contents of file list are deleted, so sort
has no data to sort and has nothing to output.
- You can redirect both the standard output and the standard error
for a command, but in this case the order in which the redirections
are listed is significant. The shell evaluates redirections from
left to right.
Example:
1>outfile 2>&1
The shell first redirects standard output to the file outfile
and then redirects standard error to the file associated with
file descriptor 1 (also outfile). This means that the output
and error messages of the command in question will both be
sent to outfile.
In a different order:
2>&1 1>outfile
Page 54 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Here the shell first redirects standard error to the file
associated with file descriptor 1 (by default, the screen,
i.e. the file /dev/tty) and then redirects the standard output
to the file outfile. In other words, only the output of the
command in question will be written to outfile, not the error
messages.
FILE NAME GENERATION
In processing the command line, the shell searches for arguments that
contain one of the following metacharacters [see COMMAND LINE PROCESS-
ING, Step 9 and expressions(5)]:
* ? [
The shell takes these arguments as patterns and matches them against
the file names in the appropriate directory. If the shell finds a file
name that matches an argument, this file name is substituted for the
argument. An argument matched by several file names is replaced by a
sorted list of all matching file names. The collating sequence is
governed by the value of the LCCOLLATE and LANG environment vari-
ables. Each file name acts as a separate argument.
If no matching file name is found, the shell uses the unaltered pat-
tern as an actual file name.
If the pattern does not contain a slash, the shell always searches for
matching file names in the current directory. If the pattern is to
match file names that begin with a dot (.), this dot must be specified
as the first character of the pattern. By contrast, periods within a
file name need not be specified in the pattern.
A pattern for file names is any string including one or more of the
following metacharacters:
* as a pattern on its own:
The shell replaces the asterisk (*) with the names of all files
in the current directory that do not begin with a dot.
Page 55 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If the current directory is empty, the shell uses the * character
as an actual file name.
as part of a pattern:
The shell replaces the asterisk with zero, one, or more charac-
ters to match file names in the current directory. A dot may also
be among the characters used to replace the asterisk, but only if
the * is not the first character in the pattern.
If the current directory is empty, or no file name matches the
specified pattern, the unaltered pattern including the * charac-
ter is treated as an actual file name.
The metacharacter * is not matched by:
- a slash (/) or
- a dot (.) when * is the first character in the pattern.
? The shell replaces the ? character with any single character to
match file names in the current directory. A ? can also be
matched by a dot (.), but only if the ? is not the first charac-
ter in the pattern.
If the current directory is empty or no matching file name is
found in it, the unaltered pattern including the ? character is
treated as an actual file name.
The metacharacter ? is not matched by:
- a slash (/) or
- a dot (.) when * is the first character in the pattern.
[s] Replaced by any one of the characters included in the set s to
match file names in the current directory. The square brackets
are mandatory.
If the current working directory is empty or does not contain any
matching names, the shell uses the pattern [s] as a file name as
it stands.
s s is a set of characters which may include any ordinary
characters other than a slash (/). If the pattern is
intended to match file names beginning with a dot (.), the
dot must not be within the square brackets. Please note that
an exclamation point (!) as the first character and a hyphen
(-) anywhere within square brackets have a special meaning.
The * and ? characters do not serve as wildcard characters
when enclosed within square brackets.
Page 56 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
[!s] Replaced by any single character other than those in set s to
match file names in the current working directory. The square
brackets are mandatory.
If the current working directory is empty or does not contain any
matching names, the shell uses the pattern [!s] as a file name as
it stands.
s as for [s].
[c1-c2]
Replaced by any one character from the bracketed range to match
file names in the current directory. The square brackets are man-
datory.
If the current working directory is empty or does not contain any
matching names, the shell uses the pattern with its brackets as a
file name as it stands.
Page 57 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
c1-c2
specifies a range of characters which includes all charac-
ters that lie between c1 and c2 in the ASCII character set.
c1 and c2 are included in the range. You can also list a
number of ranges, with no separators between them.
c1 c1 can be any ordinary character other than a slash (/).
If the pattern is to match file names that begin with a dot,
the dot must be the first character of the pattern, i.e. it
must come before the left square bracket.
Please note that an exclamation mark (!) as the first char-
acter and a dash (-) anywhere within square brackets have a
special meaning.
c2 c2 can be any ordinary character other than a slash (/).
[!c1-c2]
Replaced by any single character other than those in the brack-
eted range to match file names in the current directory. The
square brackets are mandatory.
If the current working directory is empty or does not contain any
matching names, the shell uses the pattern with its brackets as a
file name as it stands.
c1-c2
specifies a range of characters (see description of [c1-c2].
[:class:]
Character class expression. Any character of type class.
Character class expressions must always appear within a second
pair of square brackets, e.g. [c[:digit:]].
The character classes in an internationalized environment are
defined by the environment variables LCTYPE and LANG.
class is one of the following:
alpha any letter
upper any uppercase letter
lower any lowercase letter
digit any decimal digit (0 to 9)
xdigit any hexadecimal (0 to 9, a to f and A to F)
Page 58 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
alnum any alphanumeric character (letter or digit)
space any character producing white space in displayed text
(whitespace characters = blanks and tabs)
punct any punctuation character
print any printable character (including the characters in
space)
graph any character with a visible representation (excluding
the characters in space)
cntrl any control character
[=c=]
Equivalence class expression. Any character or collating element
defined as having the same relative order in the current collat-
ing sequence as c.
Equivalence class expressions must always appear within a second
pair of square brackets, e.g. [[=a=]bc].
The collating sequence in an internationalized environment is
defined by the environment variables LCCOLLATE and LANG.
[.cc.]
Collating symbol. Multi-character collating elements must be
represented in this form to distinguish them from ordinary char-
acters. An expression of this type is collated as a single char-
acter. cc has to be defined as a valid collating element in the
current collating sequence.
Collating symbols must always appear within a second pair of
square brackets, e.g. [c[.ch.]d].
The collating sequence in an internationalized environment is
defined by the environment variables LCCOLLATE and LANG.
Within the square brackets you can, without separators, concatenate
any set of c1-c2 ranges, single characters, collating symbols [.cc.],
character class expressions [:class:] and equivalence class expres-
sions [.cc.]. An exclamation point ! used to exclude specific charac-
ters or ranges must be the first character after the left square
bracket [. An exclamation point appearing anywhere else within the
brackets has no special meaning.
Page 59 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Caution:
The current character set and the current collating sequence
together determine which characters form part of a [c1-c2] range.
For example, in the locale LANG=LCCOLLATE=EnUS.ASCII the com-
mand rm [a-z]* deletes all files with names beginning with a
lowercase letter from a to z inclusive. In a number of other
locales the range a-z also include uppercase letters, and in
these environments the same command would also delete files with
names beginning with a capital letter. What is more, there are
languages, Norwegian, for example, where some letters collate
after z. So in an internationalized environment you should always
represent character classes such as lowercase letters using
expressions of the form [:class:]. Thus instead of the command
given above you would use rm [[:lower:]]*.
Shell scripts written in a non-internationalized environment (or
without allowing for the problems described above) should only be
run in a non-internationalized environment; in other words, the
NLS variables LANG, LCCOLLATE and so on should be undefined or
null.
COMMAND LINE PROCESSING
In an interactive shell you terminate a command line and pass it to
the shell by hitting CR. The portions in which the shell handles input
are governed by the characteristics of your terminal [see stty(1)].
The input to a script shell consists of the contents of the script
being read.
The command line may be made up of a number of commands separated by
command separators. In a shell script, newline characters are also
permitted as command separators. The shell processes each individual
command in succession and executes it. Hence in the following descrip-
tion the term "command line" refers to the logical unit bounded by
unescaped command separators. The shell executes all the commands in
the input before issuing its prompt again.
The shell processes a command line in several distinct steps, each of
which is performed once per command line. The sequence in which these
steps are performed is fixed. This order must be taken into account so
as to ensure that the shell processes your inputs as you require.
The way in which a command line is processed also depends on the
options that you set when calling this shell and those defined later
with the set command.
Here are the individual steps in chronological order:
1. The shell reads the command line up to the first unescaped command
separator and looks for backslashes, single and double quotes and
backquotes.
Page 60 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
2. It checks the command line for I/O redirections and variable
assignments.
3. It breaks the command line down into individual arguments (pars-
ing).
4. It substitutes values for specified variables.
5. It replaces commands between backquotes with the output they pro-
duce.
6. It redirects the standard input and/or standard output and/or
standard error to the specified files.
7. It makes assignments to variables.
8. It takes the line thus modified and parses it again, on the basis
of the argument separators assigned to the IFS variable.
9. It performs file name generation on arguments including the fol-
lowing characters or strings: * ? [...] [!...]
10. It then executes the command.
Steps 5, 6, and 7 are not executed unless the relevant metacharacters
are detected by the shell in Steps 1 and 2.
Step 1: Reading up to the first command separator
The shell reads in the command line (from the standard input or from a
file) up to the first command separator, which may be any of the fol-
lowing:
newline ; & | && ||
If you press the CTRL-D key instead of entering a command when the
shell issues its prompt, the current shell exits. A subshell running a
shell script exits after executing the last command in the script,
i.e. on reading the end-of-file character (EOF). This does not apply
when you run a shell script with the Bourne shell built-in . (dot),
however; the current shell running the script in this case does not
exit when it reads EOF.
The shell then searches its input for:
- escape symbols:
\ '...' "..."
Metacharacters escaped by any of these quoting mechanisms are hen-
ceforth protected from interpretation by the shell (see Quoting
shell metacharacters above).
Page 61 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- backquotes:
`command`
In Step 5 this expression is to be replaced by the output of com-
mand (see COMMAND SUBSTITUTION above). Step 5 (command substitu-
tion) is omitted if the shell does not find any backquotes in Step
1.
The shell protects command against interpretation by the shell, as
if the whole expression were within double quotes: "command".
If the -v option has been set in the current shell, this shell will
output the command line after the first step [see set(1)].
Step 2: Locating the metacharacters > < and =
The shell searches for the following metacharacters, which initiate
specific actions in subsequent processing steps:
> or <
redirects the standard input, standard output, or standard error
in Step 6 in accordance with the specifications that follow (see
COMMAND INPUT AND OUTPUT REDIRECTION above).
= assigns a value to a variable in Step 7 (see SHELL VARIABLES
above).
The above actions are omitted if the shell fails to find the
corresponding metacharacters at this point.
Step 3: Parsing into arguments
The shell now breaks the command line down into arguments using the
following argument separators:
blanks tabs
It then strips all argument separators from the command line.
The shell does not access the value of the IFS variable until the
eighth step, when it parses the command line again.
The shell also checks whether the first command-line argument (the
argument immediately following a command separator) is one of the fol-
lowing keywords or metacharacters (see THE SHELL AS PROGRAMMING
LANGUAGE below):
if elif case for while until { (
Page 62 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If so, it strips the keyword/left parenthesis from the command line
and then repeats Steps 1 to 3 for subsequent command lines until it
encounters a command line beginning with the partner keyword or right
parenthesis:
fi esac done } )
If a syntax error is detected, an error message is issued and further
processing is aborted.
Step 4: Substituting values for variables
The shell now searches for the $ character followed by an admissible
variable name:
$0 $1 $2 ... $9 $* $@ $# $? $! $$ $- $name ${...}
Values are then substituted for the corresponding variables, with the
null string being substituted for undefined variables (also refer to
SHELL VARIABLES and SHELL PARAMETERS above).
Step 5: Command substitution
The shell processes strings between backquotes `...`. However, this
only applies to backquotes detected by the shell in Step 1:
`command`
If you have redirected the standard output within the backquotes,
`command` will be replaced by the null string.
Several commands may be entered within backquotes, separated by com-
mand separators (also refer to COMMAND SUBSTITUTION above).
Step 6: Redirecting standard input/standard output/standard error
The shell now processes command-line arguments in which it found one
of the following characters in Step 2:
< <&- <& << <<- > >&- >& >>
Having performed the redirection, the shell strips the redirection
arguments from the command line. The command itself remains ignorant
of the redirection (also refer to COMMAND INPUT AND OUTPUT REDIRECTION
above).
Step 7: Assigning values to variables
The shell processes those points in the command line at which it found
an equals sign (=) in Step 2 (also refer to SHELL VARIABLES and THE
ENVIRONMENT above).
Page 63 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The command line processed to this point may now look something like
this:
name=value ...
If the command line contains only an assignment and no command
name, the current shell creates the name variable and assigns
value to it. There may be more than one assignment on a command
line.
Once the shell has assigned values to all the given variables, no
more processing is done on the command line. In this case Steps 8
to 10 are omitted.
From this point on, the newly defined variables will be recog-
nized in the current environment. If they are also to be passed
to a subshell, you will need to export them [see the Bourne shell
built-in export(1)]. Variables are automatically exported if the
-a option is set [see the Bourne shell built-in set(1) and the sh
command options].
name=value ... command
If the command line contains a command name in addition to an
assignment, the current shell does not add the specified variable
to the current environment, but only to the environment for
command. The command name may be preceded by more than one
assignment.
The shell then strips the assignments from the command line and
runs command in the new environment.
If you have used the set command to set the -k option in the
current shell, assignments may also follow the command name [see
set(1)].
Step 8: Second parse run
The command line is now broken down into arguments again, on the basis
of the argument separators assigned to the IFS variable. The default
input field separators are:
blank tabs newline characters
Newline characters are no longer interpreted as command separators in
Step 8.
A command line needs to be parsed again due to the substantial changes
that it has undergone since Step 3:
- variables have been replaced by their values (Step 4).
- commands in backquotes have been replaced by their output (Step 5).
Page 64 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
- keywords and parentheses have been stripped from the command line
(Step 3).
- redirection and assignment arguments have been stripped from the
command line (Steps 6 and 7).
The shell then strips all argument separators from the command line,
as well as any null strings that are not enclosed in single or double
quotes. Such unprotected null strings are produced when the shell
replaces an undefined variable with the null string. Null strings
specified in the form "" or '' are retained as arguments.
Following this parse run, the first argument consists of the command
name, while the remaining arguments constitute actual arguments to the
command.
Step 9: File name generation
The shell looks for arguments that contain any of the following meta-
characters:
* ? [
The shell takes these arguments as patterns and matches them against
the file names in the appropriate directory (see FILE NAME GENERATION
above).
If the shell finds a file name that matches an argument, this file
name is substituted for the argument. An argument matched by several
file names is replaced by a sorted list of all matching file names.
Each file name acts as a separate argument.
If no matching file name is found, the shell uses the unaltered pat-
tern as an actual file name.
If the -f option has been set in the current shell, this processing
step is omitted. If the -n option has been set in the current shell,
the shell will print the command line after Step 9, omitting Step 10
[see set(1)].
Step 10: Executing the command
The command line now contains only arguments that are required for the
execution of the command in question. The shell interprets the first
argument as the name of the command to be executed. The remaining
arguments are interpreted as arguments to this command and are passed
to the command on invocation.
Page 65 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
The shell tests the command name in the following order:
⊕ Is the command a Bourne shell built-in?
If it is, the shell itself executes the command.
If not, it proceeds to the next test.
⊕ Is the command a shell function?
If it is, the shell itself executes the function.
If not, the shell assumes that it is dealing with an external com-
mand. It therefore runs fork(2) to create (spawn) a new process.
This process is a copy of the calling shell and thus inherits its
environment. This new shell process now performs further tests:
⊕ Does the command name include a slash character / ?
If it does, the shell process attempts to run the command under the
given name using exec(2) and without accessing the PATH variable.
The command with a name including a slash will be rejected immedi-
ately by a restricted shell (see sh, option -r).
If there is no slash in the command name, the shell looks for the
name in the current hash table [see hash(1)]:
- if it is there, the shell process attempts to run the command
under the absolute path name given in the hash table, using
exec(2) and without accessing the PATH variable.
- if the command name is not in the hash table, the shell process
reads the PATH variable and forms an absolute path name from the
first path name listed there, a slash and the command name. It
then attempts to run the command under this absolute path name
using exec(2).
⊕ Can the exec(2) system call load the file?
If it can, the command is executed. With commands that are to run
in the background, the calling shell immediately returns and issues
its prompt. With all other commands, it waits for them to finish
executing.
With commands called under their basename (without path prefix),
the hash table is then updated. A command which is not yet in the
table is entered in the following format:
Page 66 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
hits cost command
1 1 absolute path name
| | |
| | |
| | command file
| |
| executable file found in first directory
| in PATH, so exec(2) only called once
|
executed once in the current shell
If the command was already in the hash table, the value in the hits
column on the corresponding line is simply incremented by 1 [see
hash(1)].
If exec(2) cannot load the file, it will be for one of the follow-
ing reasons:
- The named file is not a binary file (e.g. in a.out format). In
this case the file must be a shell script. The current shell
process reads the file and executes the commands in the steps
described here.
- The user invoking the command does not have execute permission
for the file. In this case the calling shell returns with the
error message:
command: execute permission denied.
- exec(2) cannot find the file. If the name used to invoke the
command contained a slash, or if the command was already in the
hash table (so the PATH variable was not consulted), the calling
shell returns with the error message:
command: not found.
Otherwise, the shell process again reads the PATH variable. This
time it attempts to exec(2) the command under an absolute path
name formed using the second path name listed in the PATH vari-
able.
If exec(2) still cannot find the file, the procedure is repeated
using the next path name listed in the PATH variable, and so on
until all the listed path names have been tried.
If exec(2) still has not found the file after all the path names
listed in the PATH variable have been tried, the calling shell
returns with the error message:
command: not found.
Page 67 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
THE SHELL AS PROGRAMMING LANGUAGE
The shell provides the essential elements of a programming language:
- variables
- parameters
- built-in functions (= Bourne shell built-ins)
- comments
- macros (= shell functions)
- control-flow statements.
Every command line that you enter at the shell prompt is a small shell
program in itself. The shell interprets this line on the basis of
specific rules and executes the corresponding command (see COMMAND
LINE PROCESSING above).
To write more extensive programs you use an editor. This entails
creating a file and entering in it all the commands that are to be
sequentially executed by the shell. Programs like this, known as shell
scripts or shell procedures, do not need to be compiled. When you
invoke a shell script with sh scriptname, the shell starts a subshell,
which reads, interprets, and executes each line in the file. Once all
the commands in this file have been executed, the subshell exits and
the parent shell returns.
This section provides details on:
- comments in shell scripts
- defining and invoking shell functions
- shell control-flow statements (in alphabetical order).
Comments in shell scripts
Comments are introduced by a hash character (#). All characters that
follow the # up to the first newline (escaped or unescaped) are
ignored by the shell.
Example:
Ways of entering and escaping comments in shell scripts:
date # comment
echo \# does not begin a comment
pwd # comment
date # this comment ends here -> \
echo \# a comment cannot extend over more than one line
Page 68 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If the # is escaped, its special meaning as a comment character
is lost.
The Bourne shell built-in : (colon) provides you with an additional
method of introducing a comment. This command returns an exit status
of 0 and does nothing (null command).
The comment that follows the colon must be separated from it by a
blank or a tab. The following must be observed when you use : to
introduce comments:
- The shell will normally parse elements of the comment as command-
line arguments, among other things substituting values for any
shell parameters that it encounters. Enclosing a comment in single
quotes escapes any shell metacharacters in it.
- The colon must always be the first character in a line or follow a
command separator such as a semicolon. Otherwise, it will not be
recognized as a command by the shell.
Example of comments introduced by : (colon):
: This shell script displays comments \
and prints the PID of the shell and the date
echo $$; : '$$ is the PID of the current shell'; date
With : you can have comments extending over a number of lines and
insert them between two commands on the same line.
SHELL FUNCTIONS
A shell function combines several commands under a single name.
This section describes:
- how to define a shell function,
- how to execute a shell function,
- the differences between shell functions and shell scripts, and
- the Bourne shell built-in return.
Defining a shell function
The definition of a shell function has the following format:
______________________________________________________________________
name() { commandlist;}
______________________________________________________________________
Page 69 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
name Name of the shell function. A function name may consist of
letters, digits, and underscores in any order, but must not begin
with a digit. Note: Names of built-in shell commands must not be
used in accordance with the X/Open specification [cf. list in
section BOURNE SHELL BUILT-INS above and under ksh(1)].
You cannot use the same name for a shell function and a shell
variable. If you define a shell function with a name already
given to a shell variable, the value of the shell variable will
be lost, and vice versa.
commandlist
One or more commands such as are allowed in shell scripts. Com-
mands are separated by newline characters or other command
separators. A shell function can, in turn, invoke or define
further shell functions.
The commands in commandlist are executed when you call the shell
function.
The blank after the left brace and the semicolon before the right
brace may both be replaced by newlines.
Example:
Defining the shell function ll interactively:
$ ll() {
> ls -l $*
> }
The shell function ll can now be used to simulate the ls -l com-
mand.
Once a shell function has been defined, it is known in the current
shell. The Bourne shell built-in set(1) writes all the shell variables
(with their values) and functions defined in the current shell on the
standard output. The definition of a shell function can also be
displayed by calling the Bourne shell built-in type(1) with the func-
tion name as an argument.
One limitation of shell functions is that they cannot be exported and
are hence only recognized by the shell in which they were defined.
Shell function definitions can be removed with the unset command.
All variables known in the current shell can be accessed from within a
shell function. As in the case of shell scripts, positional parameters
may also be passed with the function call. However, the positional
parameter $0 does not contain the function name but the invocation
name of the current shell or the name of the shell script, depending
on where you called the function.
Page 70 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Defining shell functions in a file
If you plan to use a shell function frequently, it is advisable to
write its definition into a file. This file can then be executed in
the current shell using the Bourne shell built-in . (dot). The func-
tion defined in this file will then be accessible in the current
shell. Multiple function definitions can also be collected together in
one file.
Executing a shell function
You invoke a shell function in the same way as a command. A shell
function is executed by the current shell itself, i.e. no subshell is
created as for shell scripts.
Example:
$ ll /dev
The shell function ll which we defined above is invoked. The
shell sets shell parameter $* to the directory name /dev.
As with a shell script, you can pass arguments to your shell function.
The current shell sets the positional parameters to these arguments.
In other words, by calling a shell function you redefine the posi-
tional parameters in the current shell (as with set).
The only limitation is that a shell function can only be called from
the shell in which it was defined.
Variable assignments within a shell function change the environment of
the current shell.
Differences between shell functions and shell scripts
Shell functions are more efficient than shell scripts. Like Bourne
shell built-ins, they are given preferential treatment by the shell,
as it does not have to create a new subshell and is not required to
load data from a file first.
A shell function is bound to the shell in which it was defined.
Every invocation of a shell function redefines all positional parame-
ters.
The Bourne shell built-in return(1) can be used to make shell func-
tions exit with a predefined exit status. This command can only be
invoked from within a shell function. By default, a shell function
exits when all the commands in it have been executed.
Page 71 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Exit status of a shell function
By default, the exit status of a shell function is the exit status of
the last command executed within the function. This exit status can be
checked with echo $?.
If you want a shell function to exit with a predefined exit status,
you should use the Bourne shell built-in return(1). As mentioned ear-
lier, this command can only be invoked from within a shell function.
As in shell scripts, you could also use the Bourne built-in exit(1) to
define an exit status. However, the exit command terminates not only
the shell script/shell function but also the executing shell.
Exiting a shell function
The Bourne shell built-in return is used to exit from shell functions.
It can be invoked with a number to define an exit status for the
corresponding function.
Shell functions also exit without return:
- when all the commands have been executed. The exit status is then
that of the last command executed.
- when the executing shell cannot find a command or detects a syntax
error; the exit status is then non-zero.
return can only be called from within a shell function.
______________________________________________________________________
return [exitstatus]
______________________________________________________________________
exitstatus
Any number between 0 and 256. This is the exit status returned by
the shell function.
If you specify a larger number, the exit status will not be the
specified number but the integer remainder of dividing the speci-
fied number by 256.
The exit status can be checked with echo $?.
exitstatus not specified:
The exit status of the shell function is that of the command last
executed before return was invoked.
Page 72 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Example:
The falsenew command can be implemented by means of the follow-
ing shell function:
falsenew() {
return 255
}
Shell control-flow statements
Control-flow statements form a part of every programming language. The
following statements are provided by the shell:
break
loop control
case ... esac
test and branch
continue
loop control
for ... do ... done
loop through list
if ... then ... elif ... then ... else ... fi
test condition and execute commands
until ... do ... done
loop with exit condition
while ... do ... done
loop with exit condition
These control-flow statements can either be entered interactively or
used in a shell script. The following keywords are only recognized by
the shell if they are entered at the beginning of a command (i.e.
after a command separator) and if they are not escaped:
case for
do if
done then
elif until
else while
esac {
Page 73 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
fi }
The braces serve to collect the output of commands enclosed within
them (see Command grouping above).
The control statements if, until, and while first test for a condi-
tion. In the shell conditions can only be given in the form of a com-
mand or a command list (see Command lists above). The shell then
evaluates the exit status.
- A condition is held to be true if the command or command list that
defines it returns an exit status of 0.
- A condition is held to be false if the command or command list that
defines it returns a non-zero exit status.
Control-flow statements can be freely combined and nested.
break - exit from loop
The Bourne shell built-in break(1) exits from the enclosing for,
until, or while loop. In a shell script, control passes to the command
following the done at the end of the broken loop.
Loops may be nested to any level. If you wish to use break to exit
from several nested loops, you can do so by calling break with the
appropriate number.
______________________________________________________________________
break [n]
______________________________________________________________________
n The number of nested for, until, or while loops to be broken by
break.
n not specified:
break terminates the immediately enclosing for, until, or while
loop; in other words, n defaults to 1.
case - test and branch
The case statement can be used to compare input with specified pat-
terns and branch to commands on the basis of the result.
Page 74 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
______________________________________________________________________
case name in
pattern[|pattern ...]) [commandlist];;
.
.
.
pattern[|pattern ...]) [commandlist]
esac
______________________________________________________________________
name Any arbitrary string, typically a shell parameter. The shell com-
pares name with the specified pattern.
pattern
String to be compared with name. The form of the patterns is the
same as that used for file name generation [see FILE NAME GENERA-
TION above and expressions(5)] except for the restrictions on
dots and slashes which apply there.
________________________________________________________________
| Metacharacter | Matches |
|_________________|_____________________________________________|
| * | any string of zero, one or more characters,|
| | including dot and slash |
|_________________|_____________________________________________|
| ? | any one character, including dot and slash |
|_________________|_____________________________________________|
| [s] | any character included in set s (after |
| | evaluation of [.cc.], [=c=] and [:class:]).|
| | s may include: |
| | |
| | - any ordinary characters (including dot . |
| | and slash /) |
| | - collating symbols [.cc.] |
| | - character class expressions [:class:] |
| | - equivalence class expressions [=c=] |
|_________________|_____________________________________________|
| [!s] | any character other than those included in |
| | set s (after evaluation of [.cc], [=c=] and|
| | [:class:]). |
|_________________|_____________________________________________|
Page 75 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
________________________________________________________________
| Metacharacter | Matches |
|_________________|_____________________________________________|
| [!c1-c2] | any one character from bracketed range; c1 |
| | and c2 are part of the range. c1 and c2 can|
| | be: |
| | |
| | - any ordinary characters (including dot . |
| | and slash /) |
| | - collating symbols [.cc.] |
| | - equivalence class expressions [=c=] |
|_________________|_____________________________________________|
| [c1-c2] | any one character other than those in the |
| | bracketed range. |
|_________________|_____________________________________________|
If name matches the given pattern, the shell executes the command
list specified after it. The case statement ends after executing
these commands.
If name does not match this pattern, the next pattern is checked.
If the same command list is to be executed for multiple patterns,
all such patterns can be entered before the command list,
separated from one another by a | (vertical bar).
If you specify the character * for pattern, any patterns that
come below it will not be checked; case will always execute the
command list after the * pattern and exit.
commandlist
List of commands to be executed if name matches the corresponding
pattern.
Every command list other than the last must be terminated with
two semicolons.
If you do not want any commands to be executed, you must at least
include the two semicolons, except in the case of the final pat-
tern.
A case statement is terminated with the keyword esac.
continue - exit from loop
The control-flow statement continue terminates the current iteration
of the enclosing for, until, or while loop. The loop resumes at the
next iteration. A shell script likewise resumes at the next iteration
of the same loop.
Page 76 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Loops may be nested to any level. If you wish to resume at the n-th
enclosing loop, you can do so by invoking continue with the appropri-
ate number.
______________________________________________________________________
continue [n]
______________________________________________________________________
n Number of the enclosing for, until, or while loop at which the
shell script is to resume.
n not specified:
The continue statement resumes the shell script at the next
iteration of the enclosing for, until, or while loop.
for - loop through list
The for statement allows you to have commands in a list repeated
several times. The loop is traversed once for each argument in the
specified list.
______________________________________________________________________
for name [in list]
do commandlist
done
______________________________________________________________________
name Name of a shell variable to which the shell successively assigns
the value of each argument in the specified list. The given
commandlist is executed after each assignment. The keyword param-
eter $name references the value currently assigned to the name
variable.
list List of arguments; the argument separators are the characters
assigned to the IFS variable. Each argument is successively
assigned as a value to the name variable, and the commandlist is
executed once for each argument. When the list of arguments is
exhausted, the for statement terminates.
If an argument contains any of the metacharacters *, ? and [...],
it is replaced by matching file names (see FILE NAME GENERATION
above).
list not specified:
in is also omitted. The shell parameter $@ is assumed as the
default, so the for loop is executed once for each argument used
in calling the shell script or defined by set in the current
shell.
Page 77 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
commandlist
List of commands to be executed as often as required.
A for loop terminates at the keyword done.
if - test condition and execute commands
The if statement allows you to test conditions and execute specific
commands, depending on the result.
The shell first executes the command list that is specified directly
after if:
- the condition is then true if the exit status returned by the final
command in the list is 0.
- the condition is false if a non-zero exit status is returned by the
final command.
___________________________________________________________________
if commandlist1
then commandlist2
[elif commandlist3
then commandlist4 ...]
[else commandlist5]
fi
___________________________________________________________________
commandlist1
Sequence of commands to be executed by the shell in order to test
the condition.
If the condition is true, the shell branches to then; if false, to
the next elif or else.
commandlist2
Sequence of commands to be executed by the shell if the condition
following if is true. The if statement ends after the execution of
these commands.
commandlist3
Sequence of commands to be executed by the shell to test the next
condition. The shell only executes commandlist3 if the condition
following if is false.
If this condition is true, the shell branches to the next then; if
false, to the next elif or else.
The elif branch is optional. If it is omitted, the then following
it is omitted as well.
Page 78 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
commandlist4
Sequence of commands to be executed by the shell if the condition
following if is false and the condition following elif is true. The
if statement is terminated after completion of these commands.
commandlist5
Sequence of commands to be executed by the shell if the conditions
following if and elif were false. The if statement terminates after
execution of these commands.
If the else segment is omitted, the shell does not execute any com-
mands unless one condition is true.
An if statement is terminated by the keyword fi.
The if statement returns an exit status of 0 if the shell has not exe-
cuted commands from a then or else branch, i.e. when no condition is
satisfied.
until - loop with exit condition
In the shell there are two loops with which an exit condition can be
given: until and while.
The until statement checks whether a specified condition is false. The
loop terminates as soon as the condition becomes true.
______________________________________________________________________
until commandlist1
do commandlist2
done
______________________________________________________________________
commandlist1
Sequence of commands executed by the shell in order to test the
condition.
If the condition is true, the until statement terminates, and the
commands from commandlist2 are not executed.
If the condition is false, the shell executes the commands from
commandlist2. The shell then tests the condition again by execut-
ing the commands from commandlist1.
commandlist2
Sequence of commands executed by the shell as long as the condi-
tion is false.
An until statement is terminated with the keyword done.
Page 79 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
If the commands after the keyword do, i.e. in the body of the loop,
are not executed at all, the exit value of the until statement is 0.
This means that the condition was false the first time it was tested.
while - loop with exit condition
In the shell there are two loops with which a termination condition
can be given: while and until.
The while statement checks whether a specified condition is true. The
loop terminates as soon as the condition becomes false.
______________________________________________________________________
while commandlist1
do commandlist2
done
______________________________________________________________________
commandlist1
Sequence of commands executed by the shell in order to test the
condition.
If the condition is true, the shell executes the commands from
commandlist2. The shell then tests the condition again by execut-
ing the commands from commandlist1.
If the condition is false, the while statement terminates, and
the commands from commandlist2 are not executed.
commandlist2
Sequence of commands executed by the shell as long as the condi-
tion is true.
A while statement is also terminated with the keyword done.
If the commands after the keyword do, i.e. in the body of the loop,
are not executed at all, the exit value of the while statement is 0.
This means that the condition was false the first time it was tested.
FURTHER DIFFERENCES BETWEEN KORN SHELL - BOURNE SHELL
Since the Korn shell (ksh) and Bourne shell (sh) do not always behave
in the same way, the shell scripts also behave differently [see also
section "Major Korn shell features not available in the Bourne shell"
in ksh(1)].
The following differences are known to exist at present:
1. If an exit is executed in a loop (for, until, while) and if the
input is read from a file, the Bourne shell quits the loop and the
Korn shell ends the script. Example of a while loop:
Page 80 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
while read i
do
echo $i
if [ "$i" = "end" ]
then
exit 199
fi
done < inputfile
retflag=$?
echo $retflag
2. The Shell cd built-in behaves differently when metacharacters (*,
?) are used.
The current directory contains the subdirectories dircmd, dirlib
and dirhead.
cd dir*
The Korn shell generates the error message "bad argument count",
and the Bourne shell changes to the directory with the first pat-
tern matching (dircmd).
3. Call parameters are interpreted differently.
Invoking at the shell level:
((/tmp/shelltest add "-po XON") 2>&1)
Korn shell:
$1 = add
$2 = -po
$1 = XON
Bourne shell:
$1 = add
$2 = -po XON
SEE ALSO
cd(1), colon(1), dot(1), echo(1), eval(1), exec(1), exit(1),
export(1), hash(1), pwd(1), read(1), readonly(1), set(1), shift(1),
test(1), times(1), trap(1), type(1), ulimit(1), umask(1), unset(1),
wait(1).
csh(1), jsh(1), ksh(1), rksh(1), xpg4sh(1).
exec(2), exit(2), signal(2), ulimit(2), umask(2), wait(2).
expressions(5), specialchar(5).
Page 81 Reliant UNIX 5.44 Printed 11/98
sh(1) sh(1)
Kochan, Wood: UNIX Shell Programming.
Manis, Meyer: The UNIX Shell-Programming Language.
Page 82 Reliant UNIX 5.44 Printed 11/98