COHERENT manpages
This page displays the COHERENT manpage for sh [The Bourne shell].
List of available manpages
Index
sh -- Command
The Bourne shell
sh [-ceiknstuvx] token ...
The COHERENT system offers two command interpreters: ksh, the Korn shell;
and sh, the Bourne shell. sh is the default COHERENT command interpreter.
The tutorial included in this manual describes the Bourne shell in detail.
As you will see from the following description, a shell is both a command
interpreter and a programming language in its own right. It would be worth
your while to spend some time in learning the rudiment's of the shell's
programming language; doing so will help you to use your COHERENT system to
best advantage.
Commands
A command consists of one or more tokens. A token is a string of text
characters (i.e., one or more alphabetic characters, punctuation marks, and
numerals) delineated by spaces, tabs, or newlines.
A simple command consists of the command's name, followed by zero or more
tokens that represent arguments to the command, names of files, or shell
operators. A complex command uses shell constructs to execute one or more
commands conditionally. In effect, a complex command is a mini-program
that you write in the shell's programming language and that sh interprets.
Shell Operators
sh recognizes a number of operators that form pipes, that redirect input
and output to commands, and that let you define the conditions under which
a given command are executed.
command | command
The pipe operator: let the output of one command serve as the input to
a second. You can combine commands with `|' to form pipelines. A
pipeline passes the standard output of the first (leftmost) command to
the standard input of the second command. For example, in the
pipeline
sort customers | uniq | more
sh invokes sort to sort the contents of file customers. It then pipes
the output of sort into the command uniq, which outputs one unique
copy of the text that is input into it. sh then pipes the output of
uniq to the command more, which displays it on your terminal one
screenful at a time. Note that under COHERENT, unlike MS-DOS, pipes
are executed concurrently: that is, sort does not have to finish its
work before uniq and more can begin to receive input and go to work.
command ; command
Execute commands on a command line sequentially. The command to the
left of the `;' executes to completion; then the command to the right
of it executes. For example, in the command line
a | b ; c | d
first executes the pipeline a | b then, when a and b are finished,
executes the pipeline c | d.
command &
Execute a command in the background. This operator must follow the
command, not precede it. It prints the process identifier of the
command on the standard output, so you can use the kill command to
kill that process should something go wrong. This operator lets you
execute more than one command simultaneously. For example, the
command
fdformat -v /dev/fha0 &
formats a high-density, 5.25-inch floppy disk in drive 0 (that is,
drive A); but while the disk is being formatted, sh returns the
command line prompt so you can immediately enter another command and
begin to work. If you did not use the `&' in this command, you
would have to wait until formatting was finished before you could
enter another command.
command && command
Execute a command upon success. sh executes the command that follows
the token `&&' only if the command that precedes it returns a
zero exit status, which signifies success. For example, the command
cd /etc
fdformat -v /dev/fha0 && badscan -o proto /dev/fha0 2400
formats a floppy disk, as described above. If the format was
successful, it then invokes the command badscan to scan the disk for
bad blocks; if it was not successful, however, it does nothing.
command || command
Execute a command upon failure. This is identical to operator
`&&', except that the second command is executed if the first
returns a non-zero status, which signifies failure. For example, the
command
/etc/fdformat -v /dev/fha0 || echo "Format failed!"
formats a floppy disk. If formatting failed, it echoes the message
Format failed! on your terminal; however, if formatting succeeds, it
does nothing.
Note that the tokens newline, `;' and `&' bind less tightly than
`&&' and `||'. sh parses command lines from left to right if
separators bind equally.
>file
Redirect into file all text written to the standard output, which
normally is written onto your screen. For example, the command
sort customers >customers.sort
sorts file customers and writes the sorted output into file
customers.sort. sh creates customers.sort if it does not exist, and
destroys its previous contents if it does exist.
>>file
Append onto file all text written to the standard output, which
normally is written onto your screen. If file does not exist, sh
creates it; however, if the file already exists, sh appends the output
onto its contents rather than destroying them. For example, the
command
sort customers.now | uniq >>customers.all
sorts file customers.now, pipes its output to command uniq, which
throws away duplicate lines of input, and appends the results onto
file customers.all.
<file
Redirect input. Here, sh reads the contents of a file and processes
them as if you had typed them from your keyboard. For example, the
command
ed textfile <edit.script
invokes the line editor ed to edit textfile; however, instead of
reading editing commands from your keyboard, sh passes to ed the
contents of file edit.script. This command would let you prepare an
editing script that you could execute repeatedly upon files rather
than having to type the same commands over and over.
<< token
Prepare a ``here document''. This operator tells sh to accept
standard input from the shell input until it reads the next line that
contains only token. For example, the command
cat >FOO <<\!
Here is some text.
!
redirects all text between `<<\!' and `!' to the cat command.
The operator `>' in turn redirects the output of cat into file FOO.
sh performs parameter substitution on the here document unless the
leading token is quoted; parameter substitution and quoting are
described below.
command 2> file
Redirect into file all text written to the standard error, which
normally is written onto your screen. For example, the command
nroff -ms textfile >textfile.p 2>textfile.err
invokes the command nroff to format the contents of textfile. It
redirects the output of nroff (i.e., the standard output) into
textfile.p; it also redirects any error messages that nroff may
generate into file textfile.err.
Please note that a command may use up to 20 streams. By default,
stream 0 is the standard input; stream 1 is the standard output; and
stream 2 is the standard error. sh lets you redirect any of these
streams individually into a file, or combine streams into each other.
<&n
sh can redirect the standard input and output to duplicate other file
descriptors. (See the Lexicon article file descriptor for details on
what these are.) This operator duplicates the standard input from file
descriptor n.
>&n
Merge one output stream with another. For example,
2>&1
merges the output of file descriptor 2 (the standard error) with that
file descriptor 1 (the standard output).
<&-
Close the standard input.
>&-
Close the standard output.
When you execute a command in the foreground, that command inherits the
file descriptors and signal traps (described below) of the invoking shell,
modified by any specified redirection. When you execute a command in the
background, it receives its input from the null device /dev/null (unless
you redirect its input and output), and ignores all interrupt and quit
signals.
File-Name Patterns
If a token contains any of the characters `?', `*', or `[', sh interprets
it as being a file-name pattern. sh ``expands'' a pattern into the names of
zero or more files in the current directory. These characters are
sometimes called ``wildcards,'' because each can represent any of several
values, depending upon how you use them:
? Match any single character except newline. For example, the command
ls name?
prints the name of any file that consists of the string name plus any
one character. If B name is followed by no characters, or is followed
by two or more characters, it will not be printed.
* Match a string of zero or more characters, other than newline. For
example, the command
ls name*
prints the name of any file that begins with the string name, followed
by zero or more other characters. Likewise, the command
ls name?*
prints the name of any file that consists of the string name followed by
at least one character. Unlike name*, the token name?* insists that be
followed by at least one character before it will be printed.
[!xyz]
Exclude characters xyz from the string search. For example, the command
ls [!abc]*
prints all files in the current directory except those that begin with
a, b, or c.
[C-c]
Enclose alternatives to match a single character. A hyphen `-'
indicates a range of characters. For example, the command
ls name[ABC]
prints the names of files nameA, nameB, and nameC (assuming, of course,
that those files exist in the current directory). The command
ls name[A-K]
prints the names of files nameA through nameK (again, assuming that they
exist in the current directory).
When sh reads a token that contains one of the above characters, it
replaces the token in the command line with an alphabetized list of file
names that match the pattern. If it finds no matches, it passes the token
unchanged to the command. For example, when you enter the command
ls name[ABC]
sh replaces the token name[ABC] with nameA, nameB, and nameC (again, if
they exist in the current directory), so the command now reads:
ls nameA nameB nameC
It then passes this second, transformed version of the command line to the
command ls.
Note that the slash `/' and leading period `.' must be matched explicitly
in a pattern. The slash, of course, separates the elements of a path name;
whereas a period at the begin of a file name usually (but not always)
indicates that that file has special significance.
Pattern Matching in Prefixes and Suffices
sh recognizes special constructs that let you match patterns in the
prefices and suffices of a string:
{#parameter}
This operator gives the number of characters in parameter. For
example, the command
foo=BAZZ ; echo ${#foo}
prints `4' on your screen, which is the number of characters that
comprise variable foo.
{string1%string2}
This returns the longest string for which the beginning of string1
matches string2. For example, if variable xyzzy is initialized to
string usr/bin/cpio, then the command
echo ${xyzzy%/*}
echoes the string usr/bin.
{string1%%string2}
This returns the shortest string for which the beginning of string1
matches string2. For example, if variable xyzzy is initialized to
usr/bin/cpio, then the command
echo ${xyzzy%/*}
echoes the string usr.
{string1#string2}
This returns the longest string for which the end of string1 matches
string2. For example, if variable plugh is initialized to the string
usr/bin/cpio , the command
echo ${plugh#*/}
echoes bin/cpio.
{string1##string2}
This returns the shortest string for which the end of string1 matches
string2. For example, given that plugh=usr/bin/cpio, the command
echo ${plugh##*/}
echoes cpio.
The following shows how to use these expressions to implement the command
basename:
basename () {
set $(echo ${1##*/}) $2
echo ${1%$2}
}
Quoting Text
From time to time, you will want to ``turn off'' the special meaning of
characters. For example, you may wish to pass a token that contains a
literal asterisk to a command; to do so, you need a way to tell sh not to
expand the token into a list of file names. Therefore, sh recognizes the
quotation operators `\', `"', and `''. These ``turn off'' (or quote) the
special meaning of operators.
The backslash `\' quotes the following character. For example, the command
ls name\*
lists a file named name*, and no other.
The shell ignores a backslash immediately followed by a newline, called a
concealed newline. This lets you give more arguments to a command than will
fit on one line. For example, the command
cc -o output file1.c file2.c file3.c \
file4.c file5.c file19.c
invokes the C compiler cc to compile a set of C source files, the names of
which extend over more than one line of input. You will find this to be
extremely helpful, especially when you write scripts and makefiles, to help
you write neat, easily read commands.
A pair of apostrophes ' ' prevents interpretation of any enclosed special
characters. For example, the command
find . -name '*.c' -print
finds and prints the name of any C-source file in the current directory and
any subdirectory. The command find interprets the `*' internally;
therefore, you want to suppress the shell's expansion of that operator,
which is accomplished by enclosing that token between apostrophes.
A pair of quotation marks " " has the same effect. Unlike apostrophes,
however, sh performs parameter substitution and command-output substitution
(described below) between quotation marks.
Environmental Variables
Environmental variables are names that can be assigned string values on a
command line, in the form
name=value
name must begin with a letter, and can contain letters, digits, and the
underscore character `_'. In shell input, `$name' or `${name}' represents
the value of the variable. Consider, for example, the commands:
TEXT=mytext
nroff -ms $TEXT >$TEXT.out
Here, sh expands $TEXT before it executes the command fBnroff. This
technique is very useful in large, complex scripts: by using variables, you
can change the behavior of the script by editing one line, rather than
having to edit numerous variables throughout the script.
Note that if an assignment precedes a command on the same command line, the
effect of the assignment is local to that command; otherwise, the effect is
permanent. For example,
kp=one testproc
assigns variable kp the value one only for the execution of the script
testproc.
sh sets the following environmental variables by default:
# The number of actual positional parameters given to the current command.
@ The list of positional parameters ``$1 $2 ...''.
* The list of positional parameters ``$1'' ``$2'' ... (the same as `$@'
unless quoted).
- Options set in the invocation of the shell or by the set command.
? The exit status returned by the last command.
! The process number of the last command invoked with `&'.
$ The process number of the current shell.
sh also references the following variables:
CWD Current working directory: this is the name of the directory in
which you are now working. Note that this variable is not common
to other implementations of sh. Code that uses it may not be
portable to other operating systems.
HOME Initial working directory; usually specified in the password file
/etc/passwd.
IFS Delimiters for tokens; usually space, tab and newline.
LASTERROR
Name of last command returning nonzero exit status.
MAIL Checked at the end of each command. If file specified in this
variable is new since last command, the shell prints ``You have
mail.'' on the user's terminal.
PATH Colon-separated list of directories searched for commands.
PS1 First prompt string. By default, this is `$'.
PS2 Second prompt string. By default, this is `>'. sh prints it
when it expects more input, such as when an open quotation-mark has
been typed but a close quotation-mark has not been typed, or within
a shell construct.
Beginning with release 4.2, the COHERENT implementation of sh performs
word-expansion on the values of the variables PS1 and PS2. For example,
setting the variables
export SITE=$(uname -s)
PS1="$SITE $USER $(pwd) > "
create a prompt that consists of your site name, your login identifier, and
your current working directory.
The special forms `${nameCtoken}' perform conditional parameter substition:
C is one of the characters `-', `=', `+', or `?'. sh replaces the form
`${name-token}' by the value of name if it is set, and by token otherwise.
It handles the `=' form in the same way, but also sets the value of name to
token if it was not set previously. sh replaces the `+' form by token if
the given name is set. It replaces the `?' form by the value of name if
set, and otherwise prints token and exits from the shell.
To unset an environmental variable, use the command unset. The command
unset -f undefines a shell function (described below).
Command Output Substitution
sh can use the output of a command as shell input (e.g., as command
arguments) by enclosing the command between grave characters ` `. For
example, to list the contents of the directories named in file dirs, use
the command
ls -l `cat dirs`
Constructs
sh lets you control execution of commands by the constructs break, case,
continue, for, if, until, and while. It recognizes each reserved word only
if it occurs unquoted as the first token of a command. This implies that a
separator must precede each reserved word in the following constructs; for
example, newline or `;' must precede do in the for construct.
The following describes each shell construct:
break [n]
Exit from a for, until, or while loop. If n is given, exit from the
preceding n levels of looping.
case token in [ pattern [ | pattern ] ...) sequence;; ] ... esac
Check token against each pattern, and execute sequence associated with
the first matching pattern.
continue [n]
Branch to the end of the nth enclosing for, until, or while construct.
for name [ in token ... ] do sequence done
Execute sequence once for each token. On each iteration, name takes
the value of the next token. If the in clause is omitted, $@ is
assumed. For example, to list all files ending with .c:
for i in *.c
do
cat $i
done
if seq1 then seq2 [ elif seq3 then seq4 ] ... [ else seq5 ] fi
Execute seq1. If the exit status is zero, execute seq2; if not,
execute the optional seq3 if given. If the exit status of seq3 is
zero, then execute seq4, and so on. If the exit status of all tested
sequences is nonzero, execute seq5.
until sequence1 [ do sequence2 ] done
Execute sequence2 until the execution of sequence1 results in an exit
status of zero.
while sequence1 [ do sequence2 ] done
Execute sequence2 as long as the execution of sequence1 results in an
exit status of zero.
(sequence)
Execute sequence within a subshell. This allows sequence to change
the current directory, for example, and not affect the enclosing
environment.
$(( ))
Perform arithmetic expansion, as described in the POSIX Standard. The
expression syntax is that of C, but the only values are signed
integers, and there are no side effects (i.e., no increment,
decrement, or assignment operators). The expression given inside this
form is first processed for further expansions, then evaluated
according to the C rules for arithmetic; the result is placed on the
output command line. This is most useful when used with return and
exit to form return values from functions and scripts.
To use $(()) with the shell's logical operators and statements, you
must use some indirection. For example:
val () {
return $((! ($*)))
}
Or:
val $(($# < 5)) && {
echo Not enough arguments
exit 1
}
Or:
val $((${#foo} > 8)) {
echo $foo is too long; use 8 characters, maximum.
exit 2
}
{sequence
} Braces simply enclose a sequence. Note that the closing `}' must
appear on the line that follows sequence.
Special Commands
sh usually executes commands with the fork system call, which creates
another process. However, sh executes the commands in this section either
directly or with an exec system call. See the Lexicon articles on fork()
and exec for details on these calls.
. script
Read and execute commands from script. Positional parameters are not
allowed. sh searches the directories named in the environmental
variable PATH to find the given script.
: [token ...]
A colon `:' indicates a ``partial comment''. sh normally ignores all
commands on a line that begins with a colon, except for redirection
and such symbols as $, {, ?, etc.
# A complete comment: if # is the first character on a line, sh ignores
all text that follows on that line.
cd dir
Change the working directory to dir. If no argument is given, change
to the home directory.
command command [arguments]
When you issue a command, sh by default looks for that command among
its set of built-in functions; if it cannot find it there, it looks
for the command in the directories set in the environmental variable
PATH. Thus, if you have given a shell function the same name as an
executable command, sh will never find the executable.
The command command tells sh to look for command in the directories
named in your PATH, and ignore any shell function with that name.
dirs sh lets you maintain a ``directory stack'', or stack of names of
directories. You can push, pop, and otherwise manipulate the contents
of this stack, which you can use for any purpose for which you need to
access a number of directory names quickly. The command dirs prints
the contents of the directory stack. The commands pushd and popd also
manipulate the directory stack.
Please note that these commands are unique to the COHERENT
implementation of sh, and are not portable to other shells. Caveat
utilitor.
eval [token ...]
Evaluate each token and treat the result as shell input.
exec [command]
Execute command directly rather than performing fork. This terminates
the current shell.
exit [status]
Set the exit status to status, if given; otherwise, the previous
status is unchanged. If the shell is not interactive, terminate it.
export [name ...]
sh executes each command in an environment, which is a set of shell-
variable names and their corresponding values. When you invoke sh, it
inherits all environmental variables that are currently set; and it,
in turn, normally passes those variables to each command it invokes.
export specifies that the shell should pass the modified value of each
given name to the environment of subsequent commands. When no name is
given, sh prints the name and value of each variable marked for
export.
getopts optstring name [arg ...]
Parse the args to command. See the Lexicon entry for getopts for
details.
popd [N ...]
Pop the directory stack. When used without an argument, it pops the
stack once. When used with one or more numeric arguments, popd pops
the specified items from the stack; item 0 is the top of the stack.
(For information on the directory stack, see the entry for the command
dirs, above.)
pushd [dir0 ... dirN]
Push dir0 through dirN onto the directory stack, and change the
current directory to the last directory pushed onto the stack. When
called without an argument, pushd exchanges the two top stack
elements. (For information on the directory stack, see the entry for
the command dirs, above.)
read name ...
Read a line from the standard input and assign each token of the input
to the corresponding shell variable name. If the input contains fewer
tokens than the name list, assign the null string to extra variables.
If the input contains more tokens, assign the last name the remainder
of the input.
readonly [name ...]
Mark each shell variable name as a read only variable. Subsequent
assignments to read only variables will not be permitted. With no
arguments, print the name and value of each read only variable.
set [-ceiknstuvx [name ...] ]
Set listed flag. If name list is provided, set shell variables name
to values of positional parameters beginning with $1.
shift
Reset positional parameter 1 to the value $2, reset positional
parameter 2 to the value $3, and so on. The original value of
positional parameter 1 is thrown away.
times
Print the total user and system times for all executed processes.
trap [command] [n ...]
Execute command if sh receives signal n. If command is omitted, reset
traps to original values. To ignore a signal, pass null string as
command. With n zero, execute command when the shell exits. With no
arguments, print a description of the traps that have already been
set.
umask [nnn]
Set user file creation mask to nnn. If no argument is given, print the
current file creation mask.
wait [pid]
Delay execution of further commands until the process that has process
identifier pid terminates. If pid is omitted, delay until every child
process has finished executing. If no child process is active, this
command finishes immediately.
Shell Functions
Beginning with COHERENT release 4.2, sh lets you declare and use functions.
In effect, a function is a script that you load permanently into memory.
A function takes the form
function() {
command $1 $2
other_function $3 $4
}
A function begins with its name. A pair of parentheses after the name tell
sh that this is a function.
The body of the function is enclosed within braces. A function can call
any command, plus any other function. Arguments are passed into the
function using the syntax $1, $2, etc., just as with a shell script.
sh keeps an internal list of the functions that you have declared. When it
reads an identifier, it first searches its list of functions; if the
identifier is not a function, sh then assumes that the identifier names a
command, and it attempts to find that command in the directories you have
named in your environmental variable PATH. Thus, if you give a function the
same name as that of an existing command, sh will always use the function
and never find the command. To suppress this behavior, use the command
command, described above.
The following example function copies one file into another:
copyfile(){
if [ $# -eq 1 ]; then
cat $1
else
cp $1 $2
fi
}
Shell Library
The file /usr/lib/shell_lib.sh holds a library of shell functions. You can
import these library with the `.' command.
This library holds the following functions:
basename "pathname" [ "suffix" "prefix" ]
This function behaves the same as the command basename, except that
you can include an option prefix to strip as well as a suffix.
file_exists "filename"
Return true if file filename exists.
find_file "filename" "path" "path" ...
Seek file in every directory named in a path.
has_prefix "string" "prefix"
Return true if string is prefixed with the string prefix.
is_empty "arg"
Return true if arg is null.
is_equal "arg1" "arg2"
Return true if arg1 and arg2 are equal.
is_numeric "argument"
Return true if argument is numeric, or false if it is not.
is_yes "arg"
Return true if arg matches `Y', `y', ``YES'', or ``yes''; one if the
argument matches `N', `n', ``NO'', or ``no''; two if it matches
anything else.
parent_of "file" [ "prefix" "suffix" ]
By default, write the path name of file. prefix and suffix are the
prefix and suffix of a command run with the output path name.
read_input "prompt" "variable" "default" "validate"
Echo prompt onto the screen. Write what the user types into variable.
If the user does not respond, set variable to default. The optional
argument validate names a function that read_input calls to evaluate
what the user types; often, this is the shell-library function
require_yes_or_no.
require_yes_or_no "arg"
This is the validation function for read_input. Check whether arg is
properly affirmative or negative.
source_path "script" [ "command " ]
Echo the name of the directory that contains script. Normally, this
function is called with the $0 of script. It pipes its output into
command if this argument is set; if it is not, it writes to the
standard output.
split_path "string" "prefix" "suffix"
This function dissects string, which must consist of colon-separated
elements, such as a PATH string. prefix and suffix give,
respectively, the prefix and suffix of the command that is run for
every component of string.
val "expression"
Return the negated value of expression. You can use this function to
turn shell arithmetic expressions into test results.
Scripts
Shell commands can be stored in a file, or script. The command
sh script [ parameter ... ]
executes the commands in script with a new subshell sh. Each parameter is a
value for a positional parameter, as described below. If you have used the
command chmod to make script executable, you may omit the sh command.
To ensure that a script is executed by sh, begin the script with the line:
#!/bin/sh
Parameters of the form `$n' represent command-line arguments within a
script. n can range from zero through nine; $0 always gives the name of
the script. These parameters are also called positional parameters.
If no corresponding parameter is given on the command line, the shell
substitutes the null string for that parameter. For example, if the script
format contains the following line:
nroff -ms $1 >$1.out
then invoking format with the command
format mytext
invokes the command nroff to format the contents of mytext, and writes the
output into file mytext.out. If, however, you invoke this command with the
command line
format mytext yourtext
the script formats mytext but ignores yourtext altogether.
Reference $* represents all command-line arguments. If, for example, we
change the contents of script format to read
nroff -ms $* >$1.out
then the command
format mytext yourtext
invoke nroff to format the contents of mytext and yourtext, and write the
output into file mytext.out.
Commands in a script can also be executed with the . (dot) command. It
resembles the sh command, but the current shell executes the script
commands without creating a new subshell or a new environment; therefore,
you cannot use command-line arguments.
Command-line Options
-c string
Read shell commands from string.
-e Exit on any error (command not found or command returning nonzero
status) if the shell is not interactive.
-i The shell is interactive, even if the terminal is not attached to it;
print prompt strings. For a shell reading a script, ignore the signals
SIGTERM and SIGINT.
-k Place all keyword arguments into the environment. Normally, sh places
only assignments to variables preceding the command into the
environment.
-n Read commands but do not execute them.
-s Read commands from the standard input and write shell output to the
standard error.
-t Read and execute one command rather than the entire file.
-u If the actual value of a shell variable is blank, report an error
rather than substituting the null string.
-v Print each line as it is read.
-x Print each command and its arguments as it is executed.
- Cancel the -x and -v options.
If the first character of argument 0 is `-', sh reads and executes the
scripts /etc/profile and $HOME/.profile before reading the standard input.
/etc/profile is a convenient place for initializing system-wide variables,
such as TIMEZONE.
Files
/etc/profile -- System-wide initial commands
$HOME/.profile -- User-specific initial commands
/dev/null -- For background input
/tmp/sh* -- Temporary files
/usr/lib/shell_lib.sh -- Library of shell functions
See Also
commands,
dup(),
environ,
exec,
fork(),
getopts,
ksh,
login,
newgrp,
set,
signal(),
test,
Using COHERENT,
vsh
Introduction to sh, the Bourne Shell, tutorial
For a list of all commands associated with sh, see the section Shell
Commands in the commands Lexicon article.
Diagnostics
sh notes on the standard error all syntax errors in commands, and all
commands that it cannot find. Syntax errors cause a noninteractive shell
to exit. It gives error messages if I/O redirection is incorrect. sh
returns the exit status of the last command executed or the status
specified by an exit command.






