








                AAnn IInnttrroodduuccttiioonn ttoo tthhee UUNNIIXX SShheellll


                          _S_. _R_. _B_o_u_r_n_e
                         Murray Hill, NJ

               _(_U_p_d_a_t_e_d _f_o_r _4_._3_B_S_D _b_y _M_a_r_k _S_e_i_d_e_n_)
            _(_F_u_r_t_h_e_r _u_p_d_a_t_e_d _b_y _P_e_r_r_y _E_. _M_e_t_z_g_e_r_)_[_+_]


                            _A_B_S_T_R_A_C_T


     The  _s_h_e_l_l  is a command programming language that pro-
     vides an interface to  the  UNIX(R)  operating  system.
     Its features include control-flow primitives, parameter
     passing, variables and string substitution.  Constructs
     such  as  _w_h_i_l_e_,  _i_f _t_h_e_n _e_l_s_e_, _c_a_s_e and _f_o_r are avail-
     able.  Two-way communication is  possible  between  the
     _s_h_e_l_l  and  commands.   String-valued parameters, typi-
     cally file names or flags, may be passed to a  command.
     A  return  code  is set by commands that may be used to
     determine control-flow, and the standard output from  a
     command may be used as shell input.

     The  _s_h_e_l_l can modify the environment in which commands
     run.  Input and output can be redirected to files,  and
     processes  that  communicate  through  `pipes'  can  be
     invoked.  Commands are found by  searching  directories
     in the file system in a sequence that can be defined by
     the user.  Commands can be read either from the  termi-
     nal  or from a file, which allows command procedures to
     be stored for later use.


11..00 IInnttrroodduuccttiioonn

The shell is both a command language and a  programming  language
that  provides  an  interface to the UNIX operating system.  This
memorandum describes, with examples, the UNIX shell.   The  first
section  covers  most  of  the  everyday requirements of terminal
-----------
[+]  This  paper  was  updated in 2010 to reflect most
features of modern POSIX shells, which all follow  the
design of S.R. Bourne's original v7 Unix shell.  Among
these are ash, bash, ksh and others.  Typically one of
these will be installed as /bin/sh on a modern system.
It does not describe  the  behavior  of  the  c  shell
(csh).   If  it's  the c shell (csh) you're interested
in, a good place to begin is William Joy's  paper  "An
Introduction to the C shell" (USD:4).









USD:3-2                         An Introduction to the UNIX Shell


users.  Some familiarity with UNIX is an advantage  when  reading
this  section; see, for example, "UNIX for beginners".1 Section 2
describes those features of the shell primarily intended for  use
within  shell  procedures.  These include the control-flow primi-
tives and string-valued  variables  provided  by  the  shell.   A
knowledge  of a programming language would be a help when reading
this section.  The last section describes the more advanced  fea-
tures of the shell.  References of the form "see _p_i_p_e (2)" are to
a section of the UNIX manual.2

11..11 SSiimmppllee ccoommmmaannddss

Simple commands consist of one or more words separated by blanks.
The  first  word  is  the name of the command to be executed; any
remaining words are passed as  arguments  to  the  command.   For
example,

          who

is  a command that prints the names of users logged in.  The com-
mand

          ls -l

prints a list of files in the current directory.  The argument _-_l
tells  _l_s to print status information, size and the creation date
for each file.

11..22 IInnppuutt oouuttppuutt rreeddiirreeccttiioonn

Most commands produce output on the standard output that is  ini-
tially  connected  to the terminal.  This output may be sent to a
file by writing, for example,

          ls -l >file

The notation _>_f_i_l_e is interpreted by the shell and is not  passed
as an argument to _l_s_.  If _f_i_l_e does not exist then the shell cre-
ates it; otherwise the original contents  of  _f_i_l_e  are  replaced
with  the output from _l_s_.  Output may be appended to a file using
the notation

          ls -l >>file

In this case _f_i_l_e is also created if it does not already exist.

The standard input of a command may be taken from a file  instead
of the terminal by writing, for example,

          wc <file

The  command _w_c reads its standard input (in this case redirected
from _f_i_l_e) and prints the number of characters, words  and  lines
found.  If only the number of lines is required then









An Introduction to the UNIX Shell                         USD:3-3


          wc -l <file

could be used.

11..33 PPiippeelliinneess aanndd ffiilltteerrss

The  standard output of one command may be connected to the stan-
dard input of another by writing the `pipe'  operator,  indicated
by ||, as in,

          ls -l || wc

Two  commands connected in this way constitute a _p_i_p_e_l_i_n_e and the
overall effect is the same as

          ls -l >file; wc <file

except that no _f_i_l_e is used.  Instead the two _p_r_o_c_e_s_s_e_s are  con-
nected  by  a  pipe (see _p_i_p_e(2)) and are run in parallel.  Pipes
are unidirectional and synchronization is achieved by halting  _w_c
when  there  is  nothing  to read and halting _l_s when the pipe is
full.

A _f_i_l_t_e_r is a command that reads its standard  input,  transforms
it  in  some way, and prints the result as output.  One such fil-
ter, _g_r_e_p_, selects from its input those lines that  contain  some
specified string.  For example,

          ls || grep old

prints  those  lines,  if any, of the output from _l_s that contain
the string _o_l_d_.  Another useful filter is _s_o_r_t.  For example,

          who || sort

will print an alphabetically sorted list of logged in users.

A pipeline may consist of more than two commands, for example,

          ls || grep old || wc -l

prints the number of file names in the current directory contain-
ing the string _o_l_d_.

11..44 BBaacckkggrroouunndd ccoommmmaannddss

To execute a command (or pipeline) the shell normally creates the
new _p_r_o_c_e_s_s_e_s and waits for them to finish.  A command may be run
without waiting for it to finish.  For example,

          cc pgm.c &

calls  the  C compiler to compile the file _p_g_m_._c_.  The trailing &&
is an operator that instructs the  shell  not  to  wait  for  the









USD:3-4                         An Introduction to the UNIX Shell


command  to  finish.   To  help  keep track of such a process the
shell reports its job number (see below) and process id following
its  creation.  Such a command is said to be running in the _b_a_c_k_-
_g_r_o_u_n_d.  By contrast, a command executed without the && is said to
be running in the _f_o_r_e_g_r_o_u_n_d.[+]

A  list of currently active processes, including ones not associ-
ated with the current shell, may be obtained using the _p_s(1) com-
mand.

11..55 FFiillee nnaammee ggeenneerraattiioonn

Many  commands  accept arguments which are file names.  For exam-
ple,

          ls -l main.c

prints information relating to the file _m_a_i_n_._c.

The shell provides a mechanism for  generating  a  list  of  file
names that match a pattern.  For example,

          ls -l *.c

generates,  as  arguments  to  _l_s_,  all file names in the current
directory that end in _._c_.  The character * is a pattern that will
match  any string including the null string.  In general _p_a_t_t_e_r_n_s
are specified as follows.

     **       Matches any string of characters including the  null
             string.

     ??       Matches any single character.

     [[......]]   Matches  any one of the characters enclosed.  A pair
             of characters separated by a minus  will  match  any
             character lexically between the pair.

For example,

          [a-z]*

matches  all names in the current directory beginning with one of
the letters _a through _z_.

          /usr/fred/test/?

matches all names in the directory //uussrr//ffrreedd//tteesstt that consist of
-----------
[+]  Even  after execution, one may move commands from
the foreground to the background, or temporarily  sus-
pend  their  execution  (which  is known as _s_t_o_p_p_i_n_g a
command.  This is described in detail in section  3.10
on _J_o_b _C_o_n_t_r_o_l..









An Introduction to the UNIX Shell                         USD:3-5


a  single  character.   If no file name is found that matches the
pattern then the pattern is passed, unchanged, as an argument.

This mechanism is useful both to save typing and to select  names
according  to  some  pattern.  It may also be used to find files.
For example,

          echo /usr/fred/*/core

finds and prints the names of all _c_o_r_e files  in  sub-directories
of  //uussrr//ffrreedd..   (_e_c_h_o is a standard UNIX command that prints its
arguments, separated by blanks.)  This last feature can be expen-
sive, requiring a scan of all sub-directories of //uussrr//ffrreedd..

There  is  one exception to the general rules given for patterns.
The character `..'  at the start of a file name must be explicitly
matched.

          echo *

will  therefore  echo all file names in the current directory not
beginning with `..'.

          echo ..*

will echo all those file names that begin with `..'.  This  avoids
inadvertent  matching  of the names `..' and `....'  which mean `the
current  directory'  and  `the  parent  directory'  respectively.
(Notice  that  _l_s  suppresses  information  for the files `..' and
`....'.)

Finally, the tilde character, `~~', may be used  to  indicate  the
home  directory  of  a  user.  The `~~' at the beginning of a path
name followed by a non-alphabetic character expands to  the  cur-
rent  user's  home  directory.  If the `~~' is followed by a login
name, it expands to the named user's home directory.   For  exam-
ple:

          ls ~
          cd ~egbert/

will  list  the  contents  of  the user's home directory and then
change to the home directory of the user ``egbert''.

11..66 QQuuoottiinngg

Characters that have a special meaning to the shell, such as <<  >>
** ?? || &&,, are called metacharacters.  A complete list of metachar-
acters is given in appendix B.  Any character preceded by a \\  is
_q_u_o_t_e_d and loses its special meaning, if any.  The \\ is elided so
that

          echo \?










USD:3-6                         An Introduction to the UNIX Shell


will echo a single ??,, and

          echo \\

will echo a single \\..  To allow long strings to be continued over
more than one line the sequence \\nneewwlliinnee is ignored.

\\  is  convenient  for quoting single characters.  When more than
one character needs quoting the above  mechanism  is  clumsy  and
error  prone.   A string of characters may be quoted by enclosing
the string between single quotes.  For example,

          echo xx'****'xx

will echo

          xx****xx

The quoted string may not contain a single quote but may  contain
newlines,  which  are  preserved.   This quoting mechanism is the
most simple and is recommended for casual use.

A third quoting mechanism using double quotes is  also  available
that  prevents interpretation of some but not all metacharacters.
Discussion of the details is deferred to section 3.5.

11..77 PPrroommppttiinngg

When the shell is used from a terminal it  will  issue  a  prompt
before  reading  a  command.  By default this prompt is `$$ '.  It
may be changed by saying, for example,

          PS1="yesdear$ "

that sets the prompt to be the string _y_e_s_d_e_a_r_$_.  If a newline  is
typed  and  further input is needed then the shell will issue the
prompt `>> '.  Sometimes this can be caused by mistyping  a  quote
mark.   If it is unexpected then entering the interrupt character
(typically CONTROL-C) will return the shell to read another  com-
mand.  This prompt may be changed by saying, for example,

          PS2=more

Entering  the  interrupt  character may also be used to terminate
most programs running as the current foreground job.

(PS1 and PS2 are _s_h_e_l_l _v_a_r_i_a_b_l_e_s, which will be described in sec-
tion 2.4 below.)

11..88 TThhee sshheellll aanndd llooggiinn

Following  _l_o_g_i_n(1)  the shell is called to read and execute com-
mands typed at the terminal.  If the user's login directory  con-
tains  the  file  ..pprrooffiillee then it is assumed to contain commands









An Introduction to the UNIX Shell                         USD:3-7


and is read by the shell before reading  any  commands  from  the
terminal.

(Most  versions of the shell also specify a file that is read and
executed on start-up whether or  not  the  shell  is  invoked  by
login.   The  ENV shell variable, described in section 2.4 below,
can be used to override the name of this  file.   See  the  shell
manual page for further information.)

11..99 SSuummmmaarryy


     +o    llss
          Print the names of files in the current directory.

     +o    llss >>ffiillee
          Put the output from _l_s into _f_i_l_e_.

     +o    llss || wwcc --ll
          Print the number of files in the current directory.

     +o    llss || ggrreepp oolldd
          Print those file names containing the string _o_l_d_.

     +o    llss || ggrreepp oolldd || wwcc --ll
          Print  the  number  of  files  whose  name contains the
          string _o_l_d_.

     +o    cccc ppggmm..cc &&
          Run _c_c in the background.

22..00 SShheellll ssccrriippttss

The shell may be used to read and execute commands contained in a
file.  For example,

          sh file [ args ...... ]

calls  the  shell  to  read  commands  from _f_i_l_e_.  Such a file is
called a _s_h_e_l_l _s_c_r_i_p_t_.  Arguments may be supplied with  the  call
and  are  referred to in _f_i_l_e using the positional parameters $$11,,
$$22,, ........

For example, if the file _w_g contains

          who || grep $1

then

          sh wg fred

is equivalent to











USD:3-8                         An Introduction to the UNIX Shell


          who || grep fred


UNIX files have three independent  attributes,  _r_e_a_d_,  _w_r_i_t_e  and
_e_x_e_c_u_t_e_.   The  UNIX  command _c_h_m_o_d(1) may be used to make a file
executable.  For example,

          chmod +x wg

will ensure that the file _w_g has execute status.  Following this,
the command

          wg fred

is equivalent to

          sh wg fred

This  allows  shell  scripts and other programs to be used inter-
changeably.  In either case a new process is created to  run  the
command.

The  `##'  character  is used as a comment character by the shell.
All characters following the `#' on a line are ignored.

A typical modern system has several different shells,  some  with
differing  command  syntax,  and it is desirable to specify which
one should be invoked when an executable script is  invoked.   If
the special comment

          #!/_p_a_t_h/_t_o/_i_n_t_e_r_p_r_e_t_e_r

appears  as the first line in a script, it is used to specify the
absolute pathname of the shell (or other interpreter) that should
be  used  to  execute the file.  (Without such a line, //bbiinn//sshh is
assumed.)  It is best if a script explicitly states what shell it
is intended for in this manner.

As  well  as  providing  names for the positional parameters, the
number of positional parameters to a script is available  as  $$##..
The name of the file being executed is available as $$00..

A  special shell parameter $$** is used to substitute for all posi-
tional parameters except $$00..  A typical use of this is to provide
some default arguments, as in,

          nroff -T450 -ms $*

which  simply  prepends  some  arguments  to those already given.
(The variable $$@@ also expands to ``all  positional  parameters'',
but is subtly different when expanded inside quotes.  See section
3.5, below.)











An Introduction to the UNIX Shell                         USD:3-9


22..11 CCoonnttrrooll ffllooww -- ffoorr

A frequent use of shell scripts is to loop through the  arguments
($$11,,  $$22,,  ......)   executing  commands once for each argument.  An
example  of  such  a  script  is  _t_e_l  that  searches  the   file
//uussrr//sshhaarree//tteellnnooss that contains lines of the form

          ......
          fred mh0123
          bert mh0789
          ......

The text of _t_e_l is

          #!/bin/sh

          for i
          do
               grep $i /usr/share/telnos
          done

The command

          tel fred

prints  those  lines in //uussrr//sshhaarree//tteellnnooss that contain the string
_f_r_e_d_.

          tel fred bert

prints those lines containing _f_r_e_d followed by those for _b_e_r_t_.

The ffoorr loop notation is recognized by the shell and has the gen-
eral form

          ffoorr _n_a_m_e iinn _w_1 _w_2 ......
          ddoo _c_o_m_m_a_n_d_-_l_i_s_t
          ddoonnee

A _c_o_m_m_a_n_d_-_l_i_s_t is a sequence of one or more simple commands sepa-
rated or terminated by  a  newline  or  semicolon.   Furthermore,
reserved  words  like ddoo and ddoonnee are only recognized following a
newline or semicolon.  _n_a_m_e is a shell variable that  is  set  to
the  words _w_1 _w_2 ...... in turn each time the _c_o_m_m_a_n_d_-_l_i_s_t following
ddoo is executed.  If iinn _w_1 _w_2 ......  is omitted  then  the  loop  is
executed  once  for  each positional parameter; that is, iinn _$_* is
assumed.

Another example of the use of the ffoorr loop is the _c_r_e_a_t_e  command
whose text is

          for i do >$i; done

The command









USD:3-10                        An Introduction to the UNIX Shell


          create alpha beta

ensures  that two empty files _a_l_p_h_a and _b_e_t_a exist and are empty.
The notation _>_f_i_l_e may be used on its own to create or clear  the
contents of a file.  Notice also that a semicolon (or newline) is
required before ddoonnee..

22..22 CCoonnttrrooll ffllooww -- ccaassee

A multiple way branch is provided for by the ccaassee notation.   For
example,

          case $# in
               1)   cat >>$1 ;;
               2)   cat >>$2 <$1 ;;
               *)   echo 'usage: append [ from ] to' ;;
          esac

is an _a_p_p_e_n_d command.  When called with one argument as

          append file

$$##  is the string _1 and the standard input is copied onto the end
of _f_i_l_e using the _c_a_t command.

          append file1 file2

appends the contents of _f_i_l_e_1 onto _f_i_l_e_2_.  If the number of argu-
ments  supplied  to _a_p_p_e_n_d is other than 1 or 2 then a message is
printed indicating proper usage.

The general form of the ccaassee command is

          ccaassee _w_o_r_d iinn
               _p_a_t_t_e_r_n)) _c_o_m_m_a_n_d_-_l_i_s_t;;;;
               ......
          eessaacc

The shell attempts to match _w_o_r_d with each _p_a_t_t_e_r_n_, in the  order
in which the patterns appear.  If a match is found the associated
_c_o_m_m_a_n_d_-_l_i_s_t is executed and execution of the ccaassee  is  complete.
Since * is the pattern that matches any string it can be used for
the default case.

A word of caution: no check is made to ensure that only one  pat-
tern  matches  the  case argument.  The first match found defines
the set of commands to be executed.  In  the  example  below  the
commands following the second * will never be executed.

          case $# in
               *) ...... ;;
               *) ...... ;;
          esac










An Introduction to the UNIX Shell                        USD:3-11


Another example of the use of the ccaassee construction is to distin-
guish between different forms  of  an  argument.   The  following
example is a fragment of a _c_c command.

          for i
          do case $i in
                  -[ocs])     ...... ;;
                  -*)    echo "unknown flag $i" ;;
                  *.c)   /lib/c0 $i ...... ;;
                  *)     echo "unexpected argument $i" ;;
             esac
          done


To  allow  the  same commands to be associated with more than one
pattern the ccaassee command provides for alternative patterns  sepa-
rated by a ||.  For example,

          case $i in
               -x||-y)    ......
          esac

is equivalent to

          case $i in
               -[xy])    ......
          esac


The usual quoting conventions apply so that

          case $i in
               \?)  ......

will match the character ??..

22..33 HHeerree ddooccuummeennttss

The shell script _t_e_l in section 2.1 uses the file //uussrr//sshhaarree//tteell--
nnooss to supply the data for _g_r_e_p_.  An alternative  is  to  include
this data within the shell script as a _h_e_r_e document, as in,

          for i
          do grep $i <<!
             ......
             fred mh0123
             bert mh0789
             ......
          !
          done

In  this  example the shell takes the lines between <<<<!! and !!  as
the standard input for _g_r_e_p_.  The string !! is arbitrary, the doc-
ument  being  terminated  by  a  line that consists of the string









USD:3-12                        An Introduction to the UNIX Shell


following <<.

Parameters are substituted in the  document  before  it  is  made
available  to  _g_r_e_p as illustrated by the following script called
_e_d_g_.

          ed $3 <<%
          g/$1/s//$2/g
          w
          %

The call

          edg string1 string2 file

is then equivalent to the command

          ed file <<%
          g/string1/s//string2/g
          w
          %

and changes all occurrences of _s_t_r_i_n_g_1 in _f_i_l_e to _s_t_r_i_n_g_2_.   Sub-
stitution can be prevented using \ to quote the special character
$$ as in

          ed $3 <<+
          1,\$s/$1/$2/g
          w
          +

(This version of _e_d_g is equivalent to the first  except  that  _e_d
will  print  a  ??  if there are no occurrences of the string $$11..)
Substitution within a _h_e_r_e document may be prevented entirely  by
quoting the terminating string, for example,

          grep $i <<'end'
          ......
          end

The  document  is  presented  without  modification  to _g_r_e_p_.  If
parameter substitution is not required in a  _h_e_r_e  document  this
latter form is more efficient.

22..44 SShheellll vvaarriiaabblleess[[++]]

The shell provides string-valued variables.  Variable names begin
with  a  letter  and  consist of letters, digits and underscores.
Variables may be given values by writing, for example,


-----------
Also  known  as  _e_n_v_i_r_o_n_m_e_n_t  _v_a_r_i_a_b_l_e_s,,  sseeee _e_n_v_i_r_o_n_-
_m_e_n_t((77))..









An Introduction to the UNIX Shell                        USD:3-13


          user=fred box=m000 acct=mh0000

which assigns values to the variables  uusseerr,,  bbooxx  and  aacccctt..   A
variable may be set to the null string by saying, for example,

          null=

The value of a variable is substituted by preceding its name with
$$; for example,

          echo $user

will echo _f_r_e_d_.

Variables may be used interactively to provide abbreviations  for
frequently used strings.  For example,

          b=/usr/fred/bin
          mv pgm $b

will  move  the file _p_g_m from the current directory to the direc-
tory //uussrr//ffrreedd//bbiinn..  A more general  notation  is  available  for
parameter (or variable) substitution, as in,

          echo ${user}

which is equivalent to

          echo $user

and  is  used  when the parameter name is followed by a letter or
digit.  For example,

          tmp=/tmp/ps
          ps a >${tmp}a

will direct the output of _p_s to the file //ttmmpp//ppssaa,, whereas,

          ps a >$tmpa

would cause the value of the variable ttmmppaa to be substituted.

Except for $$?? the following are set initially by the  shell.   $$??
is set after executing each command.

     $$??      The  exit  status  (return code) of the last command
             executed as a decimal string.  Most commands  return
             a  zero  exit  status if they complete successfully,
             otherwise a non-zero exit status is returned.  Test-
             ing  the  value  of return codes is dealt with later
             under iiff and wwhhiillee commands.

     $$##      The number of positional  parameters  (in  decimal).
             Used,  for  example,  in the _a_p_p_e_n_d command to check









USD:3-14                        An Introduction to the UNIX Shell


             the number of parameters.

     $$$$      The process  number  of  this  shell  (in  decimal).
             Since  process numbers are unique among all existing
             processes, this string is frequently used to  gener-
             ate unique temporary file names.  For example,

                       ps a >/tmp/ps$$
                       ......
                       rm /tmp/ps$$


     $$!!      The  process  number  of the last process run in the
             background (in decimal).

     $$--      The current shell flags, such as --xx and --vv..

Some variables have a special meaning to the shell and should  be
avoided for general use.

     $$MMAAIILL   When  used interactively the shell looks at the file
             specified  by  this  variable  before  it  issues  a
             prompt.   If  the  specified  file has been modified
             since it was last looked at  the  shell  prints  the
             message  _y_o_u _h_a_v_e _m_a_i_l before prompting for the next
             command.  This variable is typically set in the file
             ..pprrooffiillee,,  in the user's login directory.  For exam-
             ple,

                       MAIL=/usr/spool/mail/fred


     $$HHOOMMEE   The default argument for the _c_d command.   The  cur-
             rent  directory  is used to resolve file name refer-
             ences that do not begin with a  //,,  and  is  changed
             using the _c_d command.  For example,

                       cd /usr/fred/bin

             makes the current directory //uussrr//ffrreedd//bbiinn..

                       cat wn

             will  print  on  the  terminal  the  file _w_n in this
             directory.  The  command  _c_d  with  no  argument  is
             equivalent to

                       cd $HOME

             This  variable  is  also  typically  set  in the the
             user's login profile.

     $$PPWWDD    The current working directory. Set by  the  _c_d  ccoomm--
             mmaanndd..









An Introduction to the UNIX Shell                        USD:3-15


     $$PPAATTHH   A  list  of  directories  that contain commands (the
             _s_e_a_r_c_h _p_a_t_h).  Each time a command  is  executed  by
             the  shell  a list of directories is searched for an
             executable file.  If $$PPAATTHH is not set then the  cur-
             rent  directory,  //bbiinn, and //uussrr//bbiinn are searched by
             default.   Otherwise  $$PPAATTHH  consists  of  directory
             names separated by ::..  For example,

                       PATH=::/usr/fred/bin::/bin::/usr/bin

             specifies  that  the  current  directory  (the  null
             string before the first ::), //uussrr//ffrreedd//bbiinn,, //bbiinn  and
             //uussrr//bbiinn  are to be searched in that order.  In this
             way individual users can have  their  own  `private'
             commands  that  are  accessible independently of the
             current directory.  If the command name contains a //
             then  this  directory  search  is not used; a single
             attempt is made to execute the command.

     $$PPSS11    The primary shell prompt string, by default, `$$ '.

     $$PPSS22    The shell prompt when further input  is  needed,  by
             default, `>> '.

     $$IIFFSS    The  set  of characters used by _b_l_a_n_k _i_n_t_e_r_p_r_e_t_a_t_i_o_n
             (see section 3.5).

     $$EENNVV    The shell reads and executes  the  commands  in  the
             file specified by this variable when it is initially
             started.  Unlike the ..pprrooffiillee file,  these  commands
             are executed by all shells, not just the one started
             at login.  (Most versions of  the  shell  specify  a
             filename  that is used if ENV is not explicitly set.
             See the manual page for your shell.)

22..55 TThhee tteesstt ccoommmmaanndd

The _t_e_s_t command, although not part of the shell, is intended for
use by shell programs.  For example,

          test -f file

returns  zero exit status if _f_i_l_e exists and non-zero exit status
otherwise.  In general _t_e_s_t evaluates a predicate and returns the
result as its exit status.  Some of the more frequently used _t_e_s_t
arguments are given here, see _t_e_s_t(1) for a  complete  specifica-
tion.

          test s         true if the argument _s is not the null string
          test -f file   true if _f_i_l_e exists
          test -r file   true if _f_i_l_e is readable
          test -w file   true if _f_i_l_e is writable
          test -d file   true if _f_i_l_e is a directory










USD:3-16                        An Introduction to the UNIX Shell


The _t_e_s_t command is known as `[[' and may be invoked as such.  For
aesthetic reasons, the command ignores a close bracket `]]'  given
at the end of a command so

          [ -f filename ]

and

          test -f filename

are  completely  equivalent.   Typically, the bracket notation is
used when _t_e_s_t is invoked inside shell control constructs.

22..66 CCoonnttrrooll ffllooww -- wwhhiillee

The actions of the ffoorr loop and the ccaassee branch are determined by
data  available  to  the  shell.  A wwhhiillee or uunnttiill loop and an iiff
tthheenn eellssee branch are also provided whose actions  are  determined
by  the  exit  status returned by commands.  A wwhhiillee loop has the
general form

          wwhhiillee _c_o_m_m_a_n_d_-_l_i_s_t_1
          ddoo _c_o_m_m_a_n_d_-_l_i_s_t_2
          ddoonnee


The value tested by the wwhhiillee command is the exit status  of  the
last  simple  command  following wwhhiillee..  Each time round the loop
_c_o_m_m_a_n_d_-_l_i_s_t_1 is executed; if a zero exit status is returned then
_c_o_m_m_a_n_d_-_l_i_s_t_2  is  executed; otherwise, the loop terminates.  For
example,

          while [ $1 ]
          do ......
             shift
          done

is equivalent to

          for i
          do ......
          done

_s_h_i_f_t is a shell command that renames the  positional  parameters
$$22,, $$33,, ...... as $$11,, $$22,, ......  and loses $$11..

Another  kind  of  use  for the wwhhiillee//uunnttiill loop is to wait until
some external event occurs and then run  some  commands.   In  an
uunnttiill loop the termination condition is reversed.  For example,

          until [ -f file ]
          do sleep 300; done
          _c_o_m_m_a_n_d_s










An Introduction to the UNIX Shell                        USD:3-17


will  loop  until _f_i_l_e exists.  Each time round the loop it waits
for 5 minutes before trying again.  (Presumably  another  process
will eventually create the file.)

The  most recent enclosing loop may be exited with the bbrreeaakk com-
mand, or the rest of the body  skipped  and  the  next  iteration
begun with the ccoonnttiinnuuee command.

The commands _t_r_u_e(1) and _f_a_l_s_e(1) return 0 and non-zero exit sta-
tuses respectively. They are sometimes of use  in  control  flow,
e.g.:

          while true
          do date; sleep 5
          done

is an infinite loop that prints the date and time every five sec-
onds.

22..77 CCoonnttrrooll ffllooww -- iiff

Also available is a general conditional branch of the form,

          iiff _c_o_m_m_a_n_d_-_l_i_s_t
          tthheenn _c_o_m_m_a_n_d_-_l_i_s_t
          eellssee _c_o_m_m_a_n_d_-_l_i_s_t
          ffii

that tests the value returned by the last simple command  follow-
ing iiff..

The  iiff  command may be used in conjunction with the _t_e_s_t command
to test for the existence of a file as in

          if [ -f file ]
          then _p_r_o_c_e_s_s _f_i_l_e
          else _d_o _s_o_m_e_t_h_i_n_g _e_l_s_e
          fi


An example of the use of iiff,, ccaassee and ffoorr constructions is  given
in section 2.10.

A multiple test iiff command of the form



















USD:3-18                        An Introduction to the UNIX Shell


          if ......
          then ......
          else if ......
               then ......
               else if ......
                    ......
                    fi
               fi
          fi

may be written using an extension of the iiff notation as,

          if ......
          then ......
          elif ......
          then ......
          elif ......
          ......
          fi


The  following  example is an implementation of the _t_o_u_c_h command
which changes the `last modified' time for a list of files.   The
command may be used in conjunction with _m_a_k_e(1) to force recompi-
lation of a list of files.

          #!/bin/sh

          flag=
          for i
          do case $i in
                  -c)    flag=N ;;
                  *)     if [ -f $i ]
                    then cp $i junk$$; mv junk$$ $i
                    elif [ $flag ]
                    then echo file \'$i\' does not exist
                    else >$i
                    fi
              esac
          done

The --cc flag is used in this command to force subsequent files  to
be  created if they do not already exist.  Otherwise, if the file
does not exist, an error message is printed.  The shell  variable
_f_l_a_g is set to some non-null string if the --cc argument is encoun-
tered.  The commands

          cp ......; mv ......

copy the file and then overwrite it with the copy,  thus  causing
the last modified date to be updated.

The sequence










An Introduction to the UNIX Shell                        USD:3-19


          if command1
          then command2
          fi

may be written

          command1 && command2

Conversely,

          command1 |||| command2

executes _c_o_m_m_a_n_d_2 only if _c_o_m_m_a_n_d_1 fails.  In each case the value
returned is that of the last simple command executed.

Placing a `!!' in front of a pipeline  inverts  its  exit  status,
almost in the manner of the C operator of the same name.  Thus:

          if ! [ -d $1 ]
          then
               echo $1 is not a directory
          fi

will print a message only if $1 is not a directory.

22..88 CCoommmmaanndd ggrroouuppiinngg

Commands may be grouped in two ways,

          {{ _c_o_m_m_a_n_d_-_l_i_s_t ;; }}

and

          (( _c_o_m_m_a_n_d_-_l_i_s_t ))


In  the  first  _c_o_m_m_a_n_d_-_l_i_s_t is simply executed.  The second form
executes _c_o_m_m_a_n_d_-_l_i_s_t as a separate process.  For example,

          (cd x; rm junk )

executes _r_m _j_u_n_k in the directory xx without changing the  current
directory of the invoking shell.

The commands

          cd x; rm junk

have  the  same effect but leave the invoking shell in the direc-
tory xx..













USD:3-20                        An Introduction to the UNIX Shell


22..99 SShheellll FFuunnccttiioonnss

A function may be defined by the syntax

          _f_u_n_c_n_a_m_e() {{ _c_o_m_m_a_n_d_-_l_i_s_t ;; }}

Functions are invoked within a script as though they  were  sepa-
rate  commands  of  the  same name.  While they are executed, the
positional parameters $$11,, $$22,, ......  are  temporarily  set  to  the
arguments passed to the function. For example:

          count() {
               echo $2 : $#
          }

          count a b c

would print `b : 3'.

22..1100 DDeebbuuggggiinngg sshheellll ssccrriippttss

The  shell provides two tracing mechanisms to help when debugging
shell scripts.  The first is invoked within the script as

          set -v

(vv for verbose) and causes lines of the script to be  printed  as
they  are  read.  It is useful to help isolate syntax errors.  It
may be invoked without modifying the script by saying

          sh -v _s_c_r_i_p_t ......

where _s_c_r_i_p_t is the name of the shell script.  This flag  may  be
used  in conjunction with the --nn flag which prevents execution of
subsequent commands.  (Note that saying _s_e_t _-_n at a terminal will
render the terminal useless until an end-of-file is typed.)

The command

          set -x

will  produce  an execution trace.  Following parameter substitu-
tion each command is printed as it is executed.   (Try  these  at
the  terminal  to  see what effect they have.)  Both flags may be
turned off by saying

          set -

and the current setting of the shell flags is available as $$--.

22..1111 TThhee mmaann ccoommmmaanndd

The following is a simple  implementation  of  the  _m_a_n  command,
which  is  used  to  display  sections of the UNIX manual on your









An Introduction to the UNIX Shell                        USD:3-21


terminal.  It is called, for example, as

               man sh
               man -t ed
               man 2 fork

In the first the manual section for _s_h is displayed..   Since  no
section is specified, section 1 is used.  The second example will
typeset (--tt option) the manual section for _e_d_.  The  last  prints
the _f_o_r_k manual page from section 2, which covers system calls.



          #!/bin/sh

          cd /usr/share/man

          # "#" is the comment character
          # default is nroff ($N), section 1 ($s)
          N=n s=1

          for i
          do case $i in
                  [1-9]*)     s=$i ;;
                  -t)    N=t ;;
                  -n)    N=n ;;
                  -*)    echo unknown flag \'$i\' ;;
                  *)     if [ -f man$s/$i.$s ]
                    then
                         ${N}roff -man man$s/$i.$s
                    else # look through all manual sections
                         found=no
                         for j in 1 2 3 4 5 6 7 8 9
                         do
                            if [ -f man$j/$i.$j ]
                            then
                                 man $j $i
                                 found=yes
                                 break
                            fi
                         done
                         case $found in
                              no) echo \'$i: manual page not found\'
                         esac
                    fi
             esac
          done

             FFiigguurree 11.. AA vveerrssiioonn ooff tthhee mmaann ccoommmmaanndd

33..00 KKeeyywwoorrdd ppaarraammeetteerrss

Shell variables may be given values by assignment or when a shell
script is  invoked.   An  argument  to  a  command  of  the  form









USD:3-22                        An Introduction to the UNIX Shell


_n_a_m_e_=_v_a_l_u_e  that  precedes  the  command  name causes _v_a_l_u_e to be
assigned to _n_a_m_e before execution of  the  command  begins.   The
value  of  _n_a_m_e in the invoking shell is not affected.  For exam-
ple,

          user=fred command

will execute _c_o_m_m_a_n_d with uusseerr set to _f_r_e_d.

The _s_e_t command may also be used  to  set  positional  parameters
from within a script.  For example,

          set -- *

will  set  $$11 to the first file name in the current directory, $$22
to the next, and so  on.   Note  that  the  first  argument,  --,
ensures  correct treatment when the first file name begins with a
-.


33..11 PPaarraammeetteerr ttrraannssmmiissssiioonn

When a command is executed both positional parameters  and  shell
variables  may  be  set  on  invocation.  Variables are also made
available implicitly to a command by specifying in  advance  that
such  parameters are to be exported from the invoking shell.  For
example,

          export user box=red

marks the variables uusseerr and  bbooxx  for  export  (setting  bbooxx  to
``red''  in  the  process).  When a command is invoked copies are
made of all exportable variables (also known as _e_n_v_i_r_o_n_m_e_n_t _v_a_r_i_-
_a_b_l_e_s)  for use within the invoked program.  Modification of such
variables within an invoked command does not affect the values in
the  invoking  shell.   It is generally true of a shell script or
other program that it cannot modify the state of its caller with-
out explicit actions on the part of the caller.

Names  whose value is intended to remain constant may be declared
_r_e_a_d_o_n_l_y_.  The form of this command is the same as  that  of  the
_e_x_p_o_r_t command,

          readonly name[=value] ......

Subsequent attempts to set readonly variables are illegal.

33..22 PPaarraammeetteerr ssuubbssttiittuuttiioonn

If  a  shell parameter is not set then the null string is substi-
tuted for it.  For example, if the variable dd is not set

          echo $d










An Introduction to the UNIX Shell                        USD:3-23


or

          echo ${d}

will echo nothing.  A default string may be given as in

          echo ${d:-..}

which will echo the value of the variable dd if it is set and  not
null  and  `..'  otherwise.  The default string is evaluated using
the usual quoting conventions so that

          echo ${d:-'*'}

will echo ** if the variable dd is not set or null.  Similarly

          echo ${d:-$1}

will echo the value of dd if it is set and not null and the  value
(if any) of $$11 otherwise.

The  notation  ${d:+..} performs the inverse operation. It substi-
tutes `..' if dd is set or  not  null,  and  otherwise  substitutes
null.

A variable may be assigned a default value using the notation

          echo ${d:=..}

which substitutes the same string as

          echo ${d:-..}

and  if  dd were not previously set or null then it will be set to
the string `..'.

If there is no sensible default then the notation

          echo ${d:?_m_e_s_s_a_g_e}

will echo the value of the variable dd if it is set and not  null,
otherwise  _m_e_s_s_a_g_e  is  printed by the shell and execution of the
shell script is abandoned.  If _m_e_s_s_a_g_e is absent then a  standard
message  is printed.  A shell script that requires some variables
to be set might start as follows:

          : ${user:?} ${acct:?} ${bin:?}
          ......

Colon (::) is a command that is built in to  the  shell  and  does
nothing  once  its  arguments have been evaluated.  If any of the
variables uusseerr,, aacccctt or bbiinn are not set then the shell will aban-
don execution of the script.










USD:3-24                        An Introduction to the UNIX Shell


33..33 CCoommmmaanndd ssuubbssttiittuuttiioonn

The  standard output from a command can be substituted in a simi-
lar way to parameters.  The command _p_w_d prints  on  its  standard
output  the  name  of the current directory.  For example, if the
current directory is //uussrr//ffrreedd//bbiinn then the commands

          d=$(pwd)

(or the older notation d=`pwd`) is equivalent to

          d=/usr/fred/bin


The entire string inside $(......) (or between grave accents  `......`)
is  taken  as the command to be executed and is replaced with the
output from the command.  (The difference between the $(......)  and
`......`  notations is that the former may be nested, while the lat-
ter cannot be.)

The command is  written  using  the  usual  quoting  conventions,
except  that  inside  `......`  a  `` must be escaped using a \\.  For
example,

          ls $(echo "$HOME")

is equivalent to

          ls $HOME

Command substitution occurs in all contexts where parameter  sub-
stitution  occurs (including _h_e_r_e documents) and the treatment of
the resulting text is the same in  both  cases.   This  mechanism
allows  string  processing  commands  to  be  used  within  shell
scripts.  An example of such a command is _b_a_s_e_n_a_m_e which  removes
a specified suffix from a string.  For example,

          basename main..c ..c

will  print  the string _m_a_i_n_.  Its use is illustrated by the fol-
lowing fragment from a _c_c command.

          case $A in
               ......
               *..c) B=$(basename $A ..c)
               ......
          esac

that sets BB to the part of $$AA with the suffix ..cc stripped.

Here are some composite examples.

     +o    ffoorr ii iinn ``llss --tt``;; ddoo ......
          The variable ii is set to the names  of  files  in  time









An Introduction to the UNIX Shell                        USD:3-25


          order, most recent first.

     +o    sseett ---- ``ddaattee``;; eecchhoo $$66 $$22 $$33,, $$44
          will print, e.g., _1_9_7_7 _N_o_v _1_, _2_3_:_5_9_:_5_9

33..44 AArriitthhmmeettiicc EExxppaannssiioonn

Within  a  $((......))  construct, integer arithmetic operations are
evaluated.  (The $ in front of variable names is optional  within
$((......)).  For example:

          x=5; y=1
          echo $(($x+3*2))
          echo $((y+=x))
          echo $y

will  print  `11',  then  `6',  then `6' again.  Most of the con-
structs permitted in C arithmetic operations are permitted though
some  (like  `++') are not universally supported -- see the shell
manual page for details.

33..55 EEvvaalluuaattiioonn aanndd qquuoottiinngg

The shell is a macro processor that provides parameter  substitu-
tion, command substitution and file name generation for the argu-
ments to commands.  This section discusses  the  order  in  which
these  evaluations  occur  and the effects of the various quoting
mechanisms.

Commands are parsed initially according to the grammar  given  in
appendix A.  Before a command is executed the following substitu-
tions occur.

     +o    parameter substitution, e.g. $$uusseerr

     +o    command substitution, e.g. $$((ppwwdd)) or ``ppwwdd``

     +o    arithmetic expansion, e.g. $$(((($$ccoouunntt++11))))

          Only one evaluation occurs so that if, for example, the
          value of the variable XX is the string _$_y then

                    echo $X

          will echo _$_y_.

     +o    blank interpretation

          Following the above substitutions the resulting charac-
          ters are broken into non-blank words (_b_l_a_n_k _i_n_t_e_r_p_r_e_t_a_-
          _t_i_o_n).  For this purpose `blanks' are the characters of
          the string $$IIFFSS.  By default, this string  consists  of
          blank,  tab  and  newline.   The  null  string  is  not
          regarded as a word unless it is quoted.  For example,









USD:3-26                        An Introduction to the UNIX Shell


                    echo ''

          will pass on the null string as the first  argument  to
          _e_c_h_o, whereas

                    echo $null

          will  call  _e_c_h_o with no arguments if the variable nnuullll
          is not set or set to the null string.

     +o    file name generation

          Each word is then scanned for the file pattern  charac-
          ters  **,,  ?? and [[......]]  and an alphabetical list of file
          names is generated to replace the word.  Each such file
          name is a separate argument.

The  evaluations  just  described also occur in the list of words
associated with a ffoorr loop.  Only substitution occurs in the _w_o_r_d
used for a ccaassee branch.

As  well  as the quoting mechanisms described earlier using \\ and
''......'' a third quoting mechanism is provided using double  quotes.
Within  double  quotes  parameter and command substitution occurs
but file name generation and the interpretation  of  blanks  does
not.  The following characters have a special meaning within dou-
ble quotes and may be quoted using \\..

          $$    parameter substitution
          $$(())  command substitution
          ``    command substitution
          ""    ends the quoted string
          \\    quotes the special characters $$ `` "" \\

For example,

          echo "$x"

will pass the value of the variable xx as  a  single  argument  to
_e_c_h_o_.  Similarly,

          echo "$*"

will  pass  the positional parameters as a single argument and is
equivalent to

          echo "$1 $2 ......"

The notation $$@@ is the same as $$** except when it is quoted.

          echo "$@"

will pass the positional parameters, unevaluated, to _e_c_h_o and  is
equivalent to









An Introduction to the UNIX Shell                        USD:3-27


          echo "$1" "$2" ......


The  following table gives, for each quoting mechanism, the shell
metacharacters that are evaluated.

                            _m_e_t_a_c_h_a_r_a_c_t_e_r
                    \    $    *    `    "    '
               '    n    n    n    n    n    t
               `    y    n    n    t    n    n
               "    y    y    n    y    t    n

                    t    terminator
                    y    interpreted
                    n    not interpreted

                     FFiigguurree 22.. QQuuoottiinngg mmeecchhaanniissmmss


In cases where more than one evaluation of a string  is  required
the built-in command _e_v_a_l may be used.  For example, if the vari-
able XX has the value _$_y, and if yy has the value _p_q_r then

          eval echo $X

will echo the string _p_q_r_.

In general the _e_v_a_l command evaluates its arguments  (as  do  all
commands) and treats the result as input to the shell.  The input
is read and the resulting command(s) executed.  For example,

          wg='eval who||grep'
          $wg fred

is equivalent to

          who||grep fred

In this example, _e_v_a_l is required since there is  no  interpreta-
tion of metacharacters, such as ||, following substitution.

33..66 EErrrroorr hhaannddlliinngg

The treatment of errors detected by the shell depends on the type
of error and on whether the shell is  being  used  interactively.
An  interactive shell is one whose input and output are connected
to a terminal.  A shell invoked with the --ii flag is also interac-
tive.

Execution  of  a  command  (see also 3.7) may fail for any of the
following reasons.

+o    Input output redirection may fail.  For example, if  a  file
     does not exist or cannot be created.









USD:3-28                        An Introduction to the UNIX Shell


+o    The command itself does not exist or cannot be executed.

+o    The  command terminates abnormally, for example, with a "bus
     error" or "memory fault".  See Figure 2 below for a complete
     list of UNIX signals.

+o    The  command terminates normally but returns a non-zero exit
     status.

In all of these cases the shell will go on to  execute  the  next
command.   Except  for  the  last  case  an error message will be
printed by the shell.  All remaining errors cause  the  shell  to
exit  from  a  script.   An interactive shell will return to read
another command from the terminal.  Such errors include the  fol-
lowing.

+o    Syntax errors.  e.g., if ...... then ...... done

+o    A signal such as interrupt.  The shell waits for the current
     command, if any, to finish execution and then  either  exits
     or returns to the terminal.

+o    Failure of any of the built-in commands such as _c_d_.

The  shell  flag --ee causes the shell to terminate if any error is
detected.

     1    hangup
     2    interrupt
     3*   quit
     4*   illegal instruction
     5*   trace trap
     6*   IOT instruction
     7*   EMT instruction
     8*   floating point exception
     9    kill (cannot be caught or ignored)
     10*  bus error
     11*  segmentation violation
     12*  bad argument to system call
     13   write on a pipe with no one to read it
     14   alarm clock
     15   software termination (from _k_i_l_l (1))


                    FFiigguurree 33.. UUNNIIXX ssiiggnnaallss[[++]]
Those  signals marked with an asterisk produce a core dump if not
caught.  However, the shell itself ignores quit which is the only
external  signal that can cause a dump.  The signals in this list
of potential interest to shell programs are 1, 2, 3, 14 and 15.


-----------
[+] Additional signals have been added in modern Unix.
See _s_i_g_v_e_c(2) or _s_i_g_n_a_l(3) for an up-to-date list.









An Introduction to the UNIX Shell                        USD:3-29


33..77 FFaauulltt hhaannddlliinngg

shell scripts normally terminate when an  interrupt  is  received
from  the terminal.  The _t_r_a_p command is used if some cleaning up
is required, such as removing temporary files.  For example,

          trap 'rm /tmp/ps$$; exit' 2

sets a trap for signal 2 (terminal interrupt), and if this signal
is received will execute the commands

          rm /tmp/ps$$; exit

_e_x_i_t  is  another built-in command that terminates execution of a
shell script.  The _e_x_i_t is required; otherwise,  after  the  trap
has been taken, the shell will resume executing the script at the
place where it was interrupted.

UNIX signals can be handled in one of three ways.   They  can  be
ignored,  in  which case the signal is never sent to the process.
They can be caught, in which case the process  must  decide  what
action  to take when the signal is received.  Lastly, they can be
left to cause termination of the process  without  it  having  to
take  any  further action.  If a signal is being ignored on entry
to the shell script, for example, by invoking  it  in  the  back-
ground (see 3.7) then _t_r_a_p commands (and the signal) are ignored.

The use of _t_r_a_p is illustrated by this modified  version  of  the
_t_o_u_c_h  command  (Figure  4).  The cleanup action is to remove the
file jjuunnkk$$$$.

          #!/bin/sh

          flag=
          trap 'rm -f junk$$; exit' 1 2 3 15
          for i
          do case $i in
                  -c)    flag=N ;;
                  *)     if test -f $i
                    then cp $i junk$$; mv junk$$ $i
                    elif test $flag
                    then echo file \'$i\' does not exist
                    else >$i
                    fi
             esac
          done


                   FFiigguurree 44.. TThhee ttoouucchh ccoommmmaanndd

The _t_r_a_p command appears before the  creation  of  the  temporary
file; otherwise it would be possible for the process to die with-
out removing the file.










USD:3-30                        An Introduction to the UNIX Shell


Since there is no signal 0 in UNIX it is used  by  the  shell  to
indicate  the  commands  to  be  executed  on exit from the shell
script.

A script may, itself, elect to ignore signals by  specifying  the
null  string  as the argument to trap.  The following fragment is
taken from the _n_o_h_u_p command.

          trap '' 1 2 3 15

which causes _h_a_n_g_u_p_, _i_n_t_e_r_r_u_p_t_, _q_u_i_t and _k_i_l_l to be ignored  both
by the script and by invoked commands.

Traps may be reset by saying

          trap 2 3

which  resets the traps for signals 2 and 3 to their default val-
ues.  A list of the current values of traps may  be  obtained  by
writing

          trap


The script _s_c_a_n (Figure 5) is an example of the use of _t_r_a_p where
there is no exit in the trap command.  _s_c_a_n takes each  directory
in  the  current  directory, prompts with its name, and then exe-
cutes commands typed at the terminal until an end of file  or  an
interrupt  is  received.   Interrupts are ignored while executing
the requested commands but cause termination when _s_c_a_n is waiting
for input.

          d=`pwd`
          for i in *
          do if test -d $d/$i
             then cd $d/$i
                  while echo "$i:"
                        trap exit 2
                        read x
                  do trap : 2; eval $x; done
             fi
          done


                   FFiigguurree 55.. TThhee ssccaann ccoommmmaanndd

_r_e_a_d  _x  is a built-in command that reads one line from the stan-
dard input and places the result in the variable xx..  It returns a
non-zero  exit  status  if  either  an  end-of-file is read or an
interrupt is received.













An Introduction to the UNIX Shell                        USD:3-31


33..88 CCoommmmaanndd eexxeeccuuttiioonn

To run a command (other than a built-in) the shell first  creates
a new process using the system call _f_o_r_k_.  The execution environ-
ment for the command includes input, output  and  the  states  of
signals,  and is established in the child process before the com-
mand is executed.  The built-in command _e_x_e_c is used in the  rare
cases when no fork is required and simply replaces the shell with
a new command.  For example, a simple version of the  _n_o_h_u_p  com-
mand looks like

          trap \'\' 1 2 3 15
          exec $*

The _t_r_a_p turns off the signals specified so that they are ignored
by subsequently created commands and _e_x_e_c replaces the  shell  by
the command specified.

Most   forms  of  input  output  redirection  have  already  been
described.  In the following _w_o_r_d is only  subject  to  parameter
and  command  substitution.   No  file  name  generation or blank
interpretation takes place so that, for example,

               echo ...... >*.c

will write its output into a file whose name is **..cc..  Input  out-
put  specifications are evaluated left to right as they appear in
the command.

> _w_o_r_d      The standard output (file descriptor 1)  is  sent  to
            the file _w_o_r_d which is created if it does not already
            exist.

>> _w_o_r_d     The standard output is sent to  file  _w_o_r_d_.   If  the
            file  exists  then  output is appended (by seeking to
            the end); otherwise the file is created.

< _w_o_r_d      The standard input (file descriptor 0) is taken  from
            the file _w_o_r_d_.

<< _w_o_r_d     The  standard  input is taken from the lines of shell
            input that follow up to but not including a line con-
            sisting  only  of  _w_o_r_d_.   If  _w_o_r_d is quoted then no
            interpretation of the document occurs.   If  _w_o_r_d  is
            not  quoted  then  parameter and command substitution
            occur and \\ is used to quote the characters \\ $$ `` and
            the  first  character  of  _w_o_r_d_.   In the latter case
            \\nneewwlliinnee is ignored (c.f. quoted strings).

>& _d_i_g_i_t    The file descriptor _d_i_g_i_t  is  duplicated  using  the
            system  call  _d_u_p  (2)  and the result is used as the
            standard output.











USD:3-32                        An Introduction to the UNIX Shell


<& _d_i_g_i_t    The standard input is duplicated from file descriptor
            _d_i_g_i_t_.

<&-         The standard input is closed.

>&-         The standard output is closed.

Any  of  the  above  may be preceded by a digit in which case the
file descriptor created is that specified by the digit instead of
the default 0 or 1.  For example,

          ...... 2>file

runs  a  command with message output (file descriptor 2) directed
to _f_i_l_e_.

          ...... 2>&1

runs a command  with  its  standard  output  and  message  output
merged.   (Strictly  speaking  file  descriptor  2  is created by
duplicating file descriptor 1 but the effect is usually to  merge
the two streams.)

33..99 IInnvvookkiinngg tthhee sshheellll

The  following  flags  are  interpreted  by  the shell when it is
invoked.  If the first character of argument  zero  is  a  minus,
then commands are read from the file ..pprrooffiillee..

--cc _s_t_r_i_n_g
     If  the  --cc  flag  is  present  then  commands are read from
     _s_t_r_i_n_g_.

--ss   If the --ss flag is present or if  no  arguments  remain  then
     commands  are read from the standard input.  Shell output is
     written to file descriptor 2.

--ii   If the --ii flag is present or if the shell input  and  output
     are attached to a terminal (as told by _g_t_t_y) then this shell
     is _i_n_t_e_r_a_c_t_i_v_e_.  In this case TERMINATE is ignored (so  that
     kkiillll  00 does not kill an interactive shell) and INTERRUPT is
     caught and ignored (so that wwaaiitt is interruptable).  In  all
     cases QUIT is ignored by the shell.

33..1100 JJoobb CCoonnttrrooll

When  a  command  or pipeline (also known as a _j_o_b) is running in
the foreground, entering the stop character (typically  CONTROL-Z
but  user  settable  with the _s_t_t_y(1) command) will usually cause
the job to stop.

The jobs associated with the  current  shell  may  be  listed  by
entering  the  _j_o_b_s command.  Each job has an associated _j_o_b _n_u_m_-
_b_e_r.  Jobs that are stopped may be continued by entering









An Introduction to the UNIX Shell                        USD:3-33


          bg %_j_o_b_n_u_m_b_e_r

and jobs may be moved to the foreground by entering

          fg %_j_o_b_n_u_m_b_e_r

If there is a sole job with  a  particular  name  (say  only  one
instance  of _c_c running), _f_g and _b_g may also use name of the com-
mand in place of the number, as in:

          bg %cc

If no `%%' clause is entered, most recently stopped job (indicated
with  a `+' by the _j_o_b_s command) will be assumed.  See the manual
page for the shell for more details.

33..1111 AAlliiaasseess

The _a_l_i_a_s command creates a so-called shell alias,  which  is  an
abbreviation  that macro-expands at run time into some other com-
mand.  For example:

          alias ls="ls -F"

would cause the command sequence llss --FF to  be  executed  whenever
the user types llss into the shell.  Note that if the user types llss
--aa, the shell will in fact execute llss --FF --aa.  The  command  aalliiaass
on  its own prints out all current aliases.  The _u_n_a_l_i_a_s command,
as in:

          unalias ls

will remove an existing alias.  Aliases can  shadow  pre-existing
commands,  as  in  the example above.  They are typically used to
override the interactive behavior of commands in small ways,  for
example to always invoke some program with a favorite option, and
are almost never found in scripts.

33..1122 CCoommmmaanndd LLiinnee EEddiittiinngg aanndd RReeccaallll

When working interactively with the shell, it is often tedious to
retype  previously  entered commands, especially if they are com-
plicated.  The shell therefore  maintains  a  so-called  _h_i_s_t_o_r_y,
which is stored in the file specified by the HHIISSTTFFIILLEE environment
variable if it is set.  Users may view, edit, and re-enter previ-
ous  lines  of  input using a small subset of the commands of the
_v_i(1)  or  _e_m_a_c_s(1)[+]  editors.   Emacs  style  editing  may  be
selected by entering


-----------
Technically, vi command  editing  is  standardized  by
POSIX  while emacs is not.  However, all modern shells
support both styles.









USD:3-34                        An Introduction to the UNIX Shell


          set -o emacs

and vi style editing may be selected with

          set -o vi

The  details  of  how  command  line editing works are beyond the
scope of this document.  See the shell manual page for details.

AAcckknnoowwlleeddggeemmeennttss

The design of the shell is based in part  on  the  original  UNIX
shell3  and  the PWB/UNIX shell,4 some features having been taken
from both.  Similarities also exist with the command interpreters
of the Cambridge Multiple Access System5 and of CTSS.6

I  would  like  to  thank Dennis Ritchie and John Mashey for many
discussions during the design of the shell.  I am  also  grateful
to  the  members  of the Computing Science Research Center and to
Joe Maranzano for their comments on drafts of this document.



RReeffeerreenncceess

1.

2.

3.

4.

5.

6.



























An Introduction to the UNIX Shell                        USD:3-35


AAppppeennddiixx AA -- GGrraammmmaarr

Note: This grammar needs updating, it is obsolete.


_i_t_e_m_:          _w_o_r_d
          _i_n_p_u_t_-_o_u_t_p_u_t
          _n_a_m_e _= _v_a_l_u_e

_s_i_m_p_l_e_-_c_o_m_m_a_n_d_: _i_t_e_m
          _s_i_m_p_l_e_-_c_o_m_m_a_n_d _i_t_e_m

_c_o_m_m_a_n_d_:  _s_i_m_p_l_e_-_c_o_m_m_a_n_d
          (( _c_o_m_m_a_n_d_-_l_i_s_t ))
          {{ _c_o_m_m_a_n_d_-_l_i_s_t }}
          ffoorr _n_a_m_e ddoo _c_o_m_m_a_n_d_-_l_i_s_t ddoonnee
          ffoorr _n_a_m_e iinn _w_o_r_d ...... ddoo _c_o_m_m_a_n_d_-_l_i_s_t ddoonnee
          wwhhiillee _c_o_m_m_a_n_d_-_l_i_s_t ddoo _c_o_m_m_a_n_d_-_l_i_s_t ddoonnee
          uunnttiill _c_o_m_m_a_n_d_-_l_i_s_t ddoo _c_o_m_m_a_n_d_-_l_i_s_t ddoonnee
          ccaassee _w_o_r_d iinn _c_a_s_e_-_p_a_r_t ...... eessaacc
          iiff _c_o_m_m_a_n_d_-_l_i_s_t tthheenn _c_o_m_m_a_n_d_-_l_i_s_t _e_l_s_e_-_p_a_r_t ffii

_p_i_p_e_l_i_n_e_: _c_o_m_m_a_n_d
          _p_i_p_e_l_i_n_e || _c_o_m_m_a_n_d

_a_n_d_o_r_:    _p_i_p_e_l_i_n_e
          _a_n_d_o_r &&&& _p_i_p_e_l_i_n_e
          _a_n_d_o_r |||| _p_i_p_e_l_i_n_e

_c_o_m_m_a_n_d_-_l_i_s_t_:  _a_n_d_o_r
          _c_o_m_m_a_n_d_-_l_i_s_t ;;
          _c_o_m_m_a_n_d_-_l_i_s_t &&
          _c_o_m_m_a_n_d_-_l_i_s_t ;; _a_n_d_o_r
          _c_o_m_m_a_n_d_-_l_i_s_t && _a_n_d_o_r

_i_n_p_u_t_-_o_u_t_p_u_t_:  >> _f_i_l_e
          << _f_i_l_e
          >>>> _w_o_r_d
          <<<< _w_o_r_d

_f_i_l_e_:          _w_o_r_d
          && _d_i_g_i_t
          && _-

_c_a_s_e_-_p_a_r_t_:     _p_a_t_t_e_r_n )) _c_o_m_m_a_n_d_-_l_i_s_t ;;;;

_p_a_t_t_e_r_n_:  _w_o_r_d
          _p_a_t_t_e_r_n || _w_o_r_d

_e_l_s_e_-_p_a_r_t_:     eelliiff _c_o_m_m_a_n_d_-_l_i_s_t tthheenn _c_o_m_m_a_n_d_-_l_i_s_t _e_l_s_e_-_p_a_r_t
          eellssee _c_o_m_m_a_n_d_-_l_i_s_t
          _e_m_p_t_y

_e_m_p_t_y_:









USD:3-36                        An Introduction to the UNIX Shell


_w_o_r_d_:          a sequence of non-blank characters

_n_a_m_e_:          a sequence of letters, digits or underscores starting with a letter

_d_i_g_i_t_:         00 11 22 33 44 55 66 77 88 99


























































An Introduction to the UNIX Shell                        USD:3-37


AAppppeennddiixx BB -- MMeettaa--cchhaarraacctteerrss aanndd RReesseerrvveedd WWoorrddss

a) syntactic

     ||     pipe symbol

     &&&&    `andf' symbol

     ||||    `orf' symbol

     ;;       command separator

     ;;;;      case delimiter

     &&       background commands

     (( ))     command grouping

     <<       input redirection

     <<<<      input from a here document

     >>       output creation

     >>>>      output append



b) patterns

     **       match any character(s) including none

     ??       match any single character

     [[......]]   match any of the enclosed characters



c) substitution

     $${{......}}  substitute shell variable

     $$((......))  substitute command output

     ``......``   substitute command output

     $$((((......))))
             substitute arithmetic expression



d) quoting











USD:3-38                        An Introduction to the UNIX Shell


     \\       quote the next character

     ''......''   quote the enclosed characters except for '

     ""......""   quote the enclosed characters except for $$ `` \\ ""



e) reserved words

     iiff tthheenn eellssee eelliiff ffii
     ccaassee iinn eessaacc
     ffoorr wwhhiillee uunnttiill ddoo ddoonnee
     !! {{  }}














































