ash
SYNOPSIS
ash [ -efIijnsxz ] [ +efIijnsxz ] [ -c command ] [ arg ]
...
COPYRIGHT
Copyright 1989 by Kenneth Almquist.
DESCRIPTION
Ash is a version of sh with features similar to those of
the System V shell. This manual page lists all the fea
tures of ash but concentrates on the ones not in other
shells.
Invocation
If the -c options is given, then the shell executes the
specified shell command. The -s flag cause the shell to
read commands from the standard input (after executing any
command specified with the -c option. If neither the -s
or -c options are set, then the first arg is taken as the
name of a file to read commands from. If this is impossi
ble because there are no arguments following the options,
then ash will set the -s flag and will read commands from
the standard input.
The shell sets the initial value of the positional parame
ters from the args remaining after any arg used as the
name of a file of commands is deleted.
The flags (other than -c) are set by preceding them with
``-'' and cleared by preceding them with ``+''; see the
set builtin command for a list of flags. If no value is
specified for the -i flag, the -s flag is set, and the
standard input and output of the shell are connected to
terminals, then the -i flag will be set. If no value is
specified for the -j flag, then the -j flag will be set if
the -i flag is set.
When the shell is invoked with the -c option, it is good
practice to include the -i flag if the command was entered
interactively by a user. For compatibility with the Sys
tem V shell, the -i option should come after the -c
option.
If the first character of argument zero to the shell is
``-'', the shell is assumed to be a login shell, and the
files /etc/profile and .profile are read if they exist.
If the environment variable SHINIT is set on entry to the
shell, the commands in SHINIT are normally parsed and exe
cuted. SHINIT is not examined if the shell is a login
shell, or if it the shell is running a shell procedure.
(A shell is considered to be running a shell procedure if
``&&'' and ``||'' are binary operators. ``&&'' executes
the first command, and then executes the second command
iff the exit status of the first command is zero. ``||''
is similar, but executes the second command iff the exit
status of the first command is nonzero. ``&&'' and ``||''
both have the same priority.
The ``|'' operator is a binary operator which feeds the
standard output of the first command into the standard
input of the second command. The exit status of the ``|''
operator is the exit status of the second command. ``|''
has a higher priority than ``||'' or ``&&''.
An if command looks like
if list
then list
[ elif list
then list ] ...
[ else list ]
fi
A while command looks like
while list
do list
done
The two lists are executed repeatedly while the exit sta
tus of the first list is zero. The until command is simi
lar, but has the word until in place of while
repeats until the exit status of the first list is zero.
The for command looks like
for variable in word...
do list
done
The words are expanded, and then the list is executed
repeatedly with the variable set to each word in turn. do
and done may be replaced with ``{'' and ``}''.
The break and continue commands look like
break [ num ]
continue [ num ]
Break terminates the num innermost for or while loops.
Continue continues with the next iteration of the num'th
(list)
or
{ list; }
The first of these executes the commands in a subshell.
A function definition looks like
name ( ) command
A function definition is an executable statement; when
executed it installs a function named name and returns an
exit status of zero. The command is normally a list
enclosed between ``{'' and ``}''.
Variables may be declared to be local to a function by
using a local command. This should appear as the first
staement of a function, and looks like
local [ variable | - ] ...
Local is implemented as a builtin command.
When a variable is made local, it inherits the initial
value and exported and readonly flags from the variable
with the same name in the surrounding scope, if there is
one. Otherwise, the variable is initially unset. Ash
uses dynamic scoping, so that if you make the variable x
local to function f, which then calls function g, refer
ences to the variable x made inside g will refer to the
variable x declared inside f, not to the global variable
named x.
The only special parameter than can be made local is
``-''. Making ``-'' local any shell options that are
changed via the set command inside the function to be
restored to their original values when the function
returns.
The return command looks like
return [ exitstatus ]
It terminates the currently executing function. Return is
implemented as a builtin command.
Simple Commands
A simple command is a sequence of words. The execution of
tional parameters (except $0, which remains unchanged) are
set to the parameters to the shell function. The vari
ables which are explicitly placed in the environment of
the command (by placing assignments to them before the
function name) are made local to the function and are set
to values given. Then the command given in the function
definition is executed. The positional parameters are
restored to their original values when the command com
pletes.
Shell builtins are executed internally to the shell, with
out spawning a new process.
When a normal program is executed, the shell runs the pro
gram, passing the parameters and the environment to the
program. If the program is a shell procedure, the shell
will interpret the program in a subshell. The shell will
reinitialize itself in this case, so that the effect will
be as if a new shell had been invoked to handle the shell
procedure, except that the location of commands located in
the parent shell will be remembered by the child. If the
program is a file beginning with ``#!'', the remainder of
the first line specifies an interpreter for the program.
The shell (or the operating system, under Berkeley UNIX)
will run the interpreter in this case. The arguments to
the interpreter will consist of any arguments given on the
first line of the program, followed by the name of the
program, followed by the arguments passed to the program.
Redirection
Input/output redirections can be intermixed with the words
in a simple command and can be placed following any of the
other commands. When redirection occurs, the shell saves
the old values of the file descriptors and restores them
when the command completes. The ``<'', ``>'', and ``>>''
redirections open a file for input, output, and appending,
respectively. The ``<&digit'' and ``>&digit'' makes the
input or output a duplicate of the file descriptor num
bered by the digit. If a minus sign is used in place of a
digit, the standard input or standard output are closed.
The ``<< word'' redirection takes input from a here docu
ment. As the shell encounters ``<<'' redirections, it
collects them. The next time it encounters an unescaped
newline, it reads the documents in turn. The word follow
ing the ``<<'' specifies the contents of the line that
terminates the document. If none of the quoting methods
('', "", or \) are used to enter the word, then the docu
ment is treated like a word inside double quotes: ``$''
and backquote are expanded and backslash can be used to
escape these and to continue long lines. The word cannot
When locating a command, the shell first looks to see if
it has a shell function by that name. Then, if PATH does
not contain an entry for "%builtin", it looks for a
builtin command by that name. Finally, it searches each
entry in PATH in turn for the command.
The value of the PATH variable should be a series of
entries separated by colons. Each entry consists of a
directory name, or a directory name followed by a flag
beginning with a percent sign. The current directory
should be indicated by an empty directory name.
If no percent sign is present, then the entry causes the
shell to search for the command in the specified direc
tory. If the flag is ``%builtin'' then the list of shell
builtin commands is searched. If the flag is ``%func''
then the directory is searched for a file which is read as
input to the shell. This file should define a function
whose name is the name of the command being searched for.
Command names containing a slash are simply executed with
out performing any of the above searches.
The Environment
The environment of a command is a set of name/value pairs.
When the shell is invoked, it reads these names and val
ues, sets the shell variables with these names to the cor
responding values, and marks the variables as exported.
The export command can be used to mark additional vari
ables as exported.
The environment of a command is constructed by construct
ing name/value pairs from all the exported shell vari
ables, and then modifying this set by the assignments
which precede the command, if any.
Expansion
The process of evaluating words when a shell procedure is
executed is called expansion. Expansion consists of four
steps: variable substitution, command substitution, word
splitting, and file name generation. If a word is the
expression following the word case in a case statement,
the file name which follows a redirection symbol, or an
assignment to the environment of a command, then the word
cannot be split into multiple words. In these cases, the
last two steps of the expansion process are omitted.
Variable Substitution
To be written.
writes to the standard output will be captured by the
shell. The final newline (if any) of the output will be
deleted; the rest of the output will be substituted for
the command in the word.
Word Splitting
When the value of a variable or the output of a command is
substituted, the resulting text is subject to word split
ting, unless the dollar sign introducing the variable or
backquotes containing the text were enclosed in double
quotes. In addition, ``$@'' is subject to a special type
of splitting, even in the presence of double quotes.
Ash uses two different splitting algorithms. The normal
approach, which is intended for splitting text separated
by which space, is used if the first character of the
shell variable IFS is a space. Otherwise an alternative
experimental algorithm, which is useful for splitting
(possibly empty) fields separated by a separator charac
ter, is used.
When performing splitting, the shell scans the replacement
text looking for a character (when IFS does not begin with
a space) or a sequence of characters (when IFS does begin
with a space), deletes the character or sequence of char
acters, and spits the word into two strings at that point.
When IFS begins with a space, the shell deletes either of
the strings if they are null. As a special case, if the
word containing the replacement text is the null string,
the word is deleted.
The variable ``$@'' is special in two ways. First, split
ting takes place between the positional parameters, even
if the text is enclosed in double quotes. Second, if the
word containing the replacement text is the null string
and there are no positional parameters, then the word is
deleted. The result of these rules is that "$@" is equiv
alent to "$1" "$2" ... "$n", where n is the number of
positional parameters. (Note that this differs from the
System V shell. The System V documentation claims that
"$@" behaves this way; in fact on the System V shell "$@"
is equivalent to "" when there are no positional
paramteters.)
File Name Generation
Unless the -f flag is set, file name generation is per
formed after word splitting is complete. Each word is
viewed as a series of patterns, separated by slashes. The
process of expansion replaces the word with the names of
all existing files whose names can be formed by replacing
Patterns
A pattern consists of normal characters, which match them
selves, and meta-characters. The meta-characters are
``!'', ``*'', ``?'', and ``[''. These characters lose
there special meanings if they are quoted. When command
or variable substitution is performed and the dollar sign
or back quotes are not double quoted, the value of the
variable or the output of the command is scanned for these
characters and they are turned into meta-characters.
Two exclamation points at the beginning of a pattern func
tion as a ``not'' operator, causing the pattern to match
any string that the remainder of the pattern does not
match. Other occurances of exclamation points in a pat
tern match exclamation points. Two exclamation points are
required rather than one to decrease the incompatibility
with the System V shell (which does not treat exclamation
points specially).
An asterisk (``*'') matches any string of characters. A
question mark matches any single character. A left
bracket (``['') introduces a character class. The end of
the character class is indicated by a ``]''; if the ``]''
is missing then the ``['' matches a ``['' rather than
introducing a character class. A character class matches
any of the characters between the square brackets. A
range of characters may be specified using a minus sign.
The character class may be complemented by making an
exclamation point the first character of the character
class.
To include a ``]'' in a character class, make it the first
character listed (after the ``!'', if any). To include a
minus sign, make it the first or last character listed.
The /u Directory
By convention, the name ``/u/user'' refers to the home
directory of the specified user. There are good reasons
why this feature should be supported by the file system
(using a feature such as symbolic links) rather than by
the shell, but ash is capable of performing this mapping
if the file system doesn't. If the mapping is done by
ash, setting the -f flag will turn it off.
Character Set
Ash silently discards nul characters. Any other character
will be handled correctly by ash, including characters
with the high order bit set.
job, then the null prefix will identify the job, so you
can refer to the job by writing ``%''. The third form
refers to the current job. The current job is the last
job to be stopped while it was in the foreground. (See
the next paragraph.) The last form identifies a job by
giving the process id of the last process in the job.
If the operating system that ash is running on supports
job control, ash will allow you to use it. In this case,
typing the suspend character (typically ^Z) while running
a command will return you to ash and will make the sus
pended command the current job. You can then continue the
job in the background by typing bg, or you can continue it
in the foreground by typing fg.
Atty
If the shell variable ATTY is set, and the shell variable
TERM is not set to ``emacs'', then ash generates appropri
ate escape sequences to talk to atty(1).
Exit Statuses
By tradition, an exit status of zero means that a command
has succeeded and a nonzero exit status indicates that the
command failed. This is better than no convention at all,
but in practice it is extremely useful to allow commands
that succeed to use the exit status to return information
to the caller. A variety of better conventions have been
proposed, but none of them has met with universal
approval. The convention used by ash and all the programs
included in the ash distribution is as follows:
0 Success.
1 Alternate success.
2 Failure.
129-... Command terminated by a signal.
The alternate success return is used by commands to indi
cate various conditions which are not errors but which
can, with a little imagination, be conceived of as less
successful than plain success. For example, test returns
1 when the tested condition is false and getopts returns 1
when there are no more options. Because this convention
is not used universally, the -e option of ash causes the
shell to exit when a command returns 1 even though that
contradicts the convention described here.
When a command is terminated by a signal, the uses 128
plus the signal number as the exit code for the command.
Builtin Commands
This concluding section lists the builtin commands which
bltin command arg...
Execute the specified builtin command. (This is use
ful when you have a shell function with the same name
as a builtin command.)
cd [ directory ]
Switch to the specified directory (default $HOME).
If the an entry for CDPATH appears in the environment
of the cd command or the shell variable CDPATH is set
and the directory name does not begin with a slash,
then the directories listed in CDPATH will be
searched for the specified directory. The format of
CDPATH is the same as that of PATH. In an interac
tive shell, the cd command will print out the name of
the directory that it actually switched to if this is
different from the name that the user gave. These
may be different either because the CDPATH mechanism
was used or because a symbolic link was crossed.
. file
The commands in the specified file are read and exe
cuted by the shell. A path search is not done to
find the file because the directories in PATH gener
ally contain files that are intended to be executed,
not read.
eval string...
The strings are parsed as shell commands and exe
cuted. (This differs from the System V shell, which
concatenates the arguments (separated by spaces) and
parses the result as a single command.)
exec [ command arg... ]
Unless command is omitted, the shell process is
replaced with the specified program (which must be a
real program, not a shell builtin or function). Any
redirections on the exec command are marked as perma
nent, so that they are not undone when the exec com
mand finishes. If the command is not found, the exec
command causes the shell to exit.
exit [ exitstatus ]
Terminate the shell process. If exitstatus is given
it is used as the exit status of the shell; otherwise
the exit status of the preceding command is used.
export name...
The specified names are exported so that they will
appear in the environment of subsequent commands.
The only way to un-export a variable is to unset it.
Ash allows the value of a variable to be set at the
same time it is exported by writing
hash -rv command...
The shell maintains a hash table which remembers the
locations of commands. With no arguments whatsoever,
the hash command prints out the contents of this
table. Entries which have not been looked at since
the last cd command are marked with an asterisk; it
is possible for these entries to be invalid.
With arguments, the hash command removes the speci
fied commands from the hash table (unless they are
functions) and then locates them. With the -v
option, hash prints the locations of the commands as
it finds them. The -r option causes the hash command
to delete all the entries in the hash table except
for functions.
jobid [ job ]
Print the process id's of the processes in the job.
If the job argument is omitted, use the current job.
jobs
This command lists out all the background processes
which are children of the current shell process.
lc [ function-name ]
The function name is defined to execute the last com
mand entered. If the function name is omitted, the
last command executed is executed again. This com
mand only works if the -i flag is set.
pwd
Print the current directory. The builtin command may
differ from the program of the same name because the
builtin command remembers what the current directory
is rather than recomputing it each time. This makes
it faster. However, if the current directory is
renamed, the builtin version of pwd will continue to
print the old name for the directory.
read [ -p prompt ] [ -e ] variable...
The prompt is printed if the -p option is specified
and the standard input is a terminal. Then a line is
read from the standard input. The trailing newline
is deleted from the line and the line is split as
described in the section on word splitting above, and
the pieces are assigned to the variables in order.
If there are more pieces than variables, the remain
ing pieces (along with the characters in IFS that
separated them) are assigned to the last variable.
If there are more variables than pieces, the remain
ing variables are assigned the null string.
readonly name=value
With no arguments the readonly command lists the
names of all read only variables.
set [ { -options | +options | -- } ] arg...
The set command performs three different functions.
With no arguments, it lists the values of all shell
variables.
If options are given, it sets the specified option
flags, or clears them if the option flags are intro
duced with a + rather than a -. Only the first argu
ment to set can contain options. The possible
options are:
-e Causes the shell to exit when a command termi
nates with a nonzero exit status, except when the
exit status of the command is explicitly tested.
The exit status of a command is considered to be
explicitly tested if the command is used to con
trol an if, elif, while, or until; or if the com
mand is the left hand operand of an ``&&'' or
``||'' operator.
-f Turn off file name generation.
-I Cause the shell to ignore end of file conditions.
(This doesn't apply when the shell a script
sourced using the ``.'' command.) The shell
will in fact exit if it gets 50 eof's in a row.
-i Make the shell interactive. This causes the
shell to prompt for input, to trap interrupts, to
ignore quit and terminate signals, and to return
to the main command loop rather than exiting on
error.
-j Turns on Berkeley job control, on systems that
support it. When the shell starts up, the -j is
set by default if the -i flag is set.
-n Causes the shell to read commands but not execute
them. (This is marginally useful for checking
the syntax of scripts.)
-s If this flag is set when the shell starts up, the
shell reads commands from its standard input.
The shell doesn't examine the value of this flag
any other time.
will leave the value of the positional parameters
unchanged, so to set the positional parameters to set
of values that may be empty, execute the command
shift $#
first to clear out the old values of the positional
parameters.
setvar variable value
Assigns value to variable. (In general it is better
to write variable=value rather than using setvar.
Setvar is intended to be used in functions that
assign values to variables whose names are passed as
parameters.)
shift [ n ]
Shift the positional parameters n times. A shift
sets the value of $1 to the value of $2, the value of
$2 to the value of $3, and so on, decreasing the
value of $# by one. If there are zero positional
parameters, shifting doesn't do anything.
trap [ action ] signal...
Cause the shell to parse and execute action when any
of the specified signals are received. The signals
are specified by signal number. Action may be null
or omitted; the former causes the specified signal to
be ignored and the latter causes the default action
to be taken. When the shell forks off a subshell, it
resets trapped (but not ignored) signals to the
default action. The trap command has no effect on
signals that were ignored on entry to the shell.
umask [ mask ]
Set the value of umask (see umask(2)) to the speci
fied octal value. If the argument is omitted, the
umask value is printed.
unset name...
The specified variables and functions are unset and
unexported. If a given name corresponds to both a
variable and a function, both the variable and the
function are unset.
wait [ job ]
Wait for the specified job to complete and return the
exit status of the last process in the job. If the
argument is omitted, wait for all jobs to complete
and the return an exit status of zero.
EXAMPLES
ensures that the function will return an exit status of
zero if it successfully changes to a directory that does
not contain a ``.enter'' file. Redefining existing com
mands is not always a good idea, but this example shows
that you can do it if you want to.
The suspend function distributed with ash looks like
# Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
# This file is part of ash, which is distributed under the terms
# specified by the Ash General Public License.
suspend() {
local -
set +j
kill -TSTP 0
}
This turns off job control and then sends a stop signal to
the current process group, which suspends the shell.
(When job control is turned on, the shell ignores the TSTP
signal.) Job control will be turned back on when the
function returns because ``-'' is local to the function.
As an example of what not to do, consider an earlier ver
sion of suspend:
suspend() {
suspend_flag=$-
set +j
kill -TSTP 0
set -$suspend_flag
}
There are two problems with this. First, suspend_flag is
a global variable rather than a local one, which will
cause problems in the (unlikely) circumstance that the
user is using that variable for some other purpose. Sec
ond, consider what happens if shell received an interrupt
signal after it executes the first set command but before
it executes the second one. The interrupt signal will
abort the shell function, so that the second set command
will never be executed and job control will be left off.
The first version of suspend avoids this problem by turn
ing job control off only in a local copy of the shell
options. The local copy of the shell options is discarded
when the function is terminated, no matter how it is ter
minated.
HINTS
Shell variables can be used to provide abbreviations for
things which you type frequently. For example, I set
export h=$HOME
Word splitting and file name generation are performed by
default, and you have to explicitly use double quotes to
suppress it. This is backwards, but you can learn to live
with it. Just get in the habit of writing double quotes
around variable and command substitutions, and omit them
only when you really want word splitting and file name
generation. If you want word splitting but not file name
generation, use the -f option.
AUTHORS
Kenneth Almquist
SEE ALSO
echo(1), expr(1), line(1), pwd(1), true(1).
BUGS
When command substitution occurs inside a here document,
the commands inside the here document are run with their
standard input closed. For example, the following will
not word because the standard input of the line command
will be closed when the command is run:
cat <<-!
Line 1: $(line)
Line 2: $(line)
!
Unsetting a function which is currently being executed may
cause strange behavior.
The shell syntax allows a here document to be terminated
by an end of file as well as by a line containing the ter
minator word which follows the ``<<''. What this means is
that if you mistype the terminator line, the shell will
silently swallow up the rest of your shell script and
stick it in the here document.
March 7, 1991 SH(1)
|