.H 1 "INTRODUCTION"
.P
In any programming project,
some effort is used to build the end product.
The remainder is consumed in building the supporting tools and
procedures used to manage and maintain that end product.
The second effort can far exceed the first,
especially in larger projects.
A good command language can be an invaluable tool
in such situations.
If it is a flexible programming language,
it can be used to solve many internal support problems without requiring
compilable programs to be written, debugged, and maintained;
its most important advantage is the ability to
get the job done
.I now .
For a perspective on the motivations for using a command language
in this way, see
[1,3,4].
.P
When users log into a \*u\(dg
.FS \(dg
UNIX is a Trademark of Bell Laboratories.
.FE
system,
they communicate with an instance of the shell
that reads commands typed at the terminal
and arranges for their execution.
Thus, the shell's most important function is to provide a
good interface for human beings.
In addition, a sequence of commands may be preserved
for repeated use by saving it in a file,
called a
.I "shell procedure" ,
a
.I "command file" ,
or a
.I runcom ,
according to local preference.
.P
Some \*u users need little knowledge of the shell to do their work;
others make heavy use of its programming features.
This tutorial may be read in several different ways,
depending on the reader's interests.
A brief discussion of the \*u environment
is found in \(sc2.
The discussion in \(sc3
covers aspects of the shell that are important for everyone,
while all of \(sc4 and most of \(sc5 are mainly
of interest to those who write shell procedures.
A group of annotated shell procedures
is given in \(sc6.
Finally, a brief discussion of efficiency is offered in \(sc7;
this is found in its proper place (at the end),
and is intended for those who write
especially time-consuming shell procedures.
.P
Complete beginners should
.I not\^
be reading this tutorial,
but should work their way through other available tutorials first.
See
[12] for an appropriate
plan of study.
All the \f2commands\^\fP mentioned below are described
in
Section~1 of the \f2U\s-1NIX\s+1 User's Manual\^\fP [5], while
\f2system calls\^\fP are described in Section~2
and \f2subroutines\^\fP in Section~3 thereof.
.H 1 "OVERVIEW \|OF \|THE \|UNIX \|ENVIRONMENT"
.P
Full understanding of what follows
depends on familiarity with \*u;
[11] is useful for that,
and it would be helpful to read [6] and at least one of
[7,8].
For completeness, a short overview of the most relevant concepts
is given below.
.H 2 "File \|System"
.P
The \*u file system's overall structure is that of a rooted tree
composed of
.I directories\^
and other files.
A
simple
.I "file name\^"
is a sequence of characters other than a
slash
(%/%).
A
.I "path name\^"
is a sequence of directory names followed by a simple file name,
each separated from the previous one by a
%/%.
If a path name begins with a
%/%,
the search for the file begins at the \f2root\^\fP of the entire tree;
otherwise, it begins at the user's
.I "current directory\^"
(also known as the
.I "working directory" ).
The first kind of name is often called a
\f2full\^\fP (or \f2absolute\fP) \f2path name\fP
because it is invariant with regard to the user's current directory.
The latter is often called a
.I "relative path name" ,
because it specifies a path relative to the current directory.
The user may change the current directory at any time by using the
%cd%
command.
In most cases,
a file name and its corresponding path name may be used interchangeably.
Some sample names are:
.VL 23 3
.LI %/%
the absolute path name of the root directory of the entire file
structure.
.LI %/bin%
directory containing most of the frequently used public commands.
.LI %/a1/tf/jtb/bin%
a full path name typical of multi-person
programming projects.
This one happens to be a private directory of commands belonging to
person
%jtb%
in project
%tf%;
%a1%
is the name of a \f2file system\^\fP.
.LI %bin/x%
a relative path name;
it names file
%x%
in subdirectory
%bin%
of the current directory.
If the current directory is
%/%,
it names
%/bin/x%.
If the current directory is
%/a1/tf/jtb%,
it names
%/a1/tf/jtb/bin/x%.
.LI %memox%
name of a file in the current directory.
.LE
.P
The \*u file system provides special shorthand
notations for
the current directory and the \f2parent\^\fP directory of the current directory:
.VL 11 3
.LI %.%
is the generic name of the current directory;
%./memox%
names the same file as
%memox%
if such a file exists in the current directory.
.LI %..%
is the generic name of the parent directory of the current directory;
if you type:
.CW
cd ..
.CN
then the parent directory of your current working directory will become your new current
directory.
.LE
.H 2 "UNIX \|Processes"
.P
.in +\w'~\(rh~\|'u
.ti -\w'~\(rh~\|'u
.I
~\(rh~\|Beginners should skip this section
on first reading.
.R
.in -\w'~\(rh~\|'u
.P
An
.I image\^
is a computer execution environment, including memory image, register values,
name of the current directory, status of open files, information recorded at
login time, and various other items.
A
.I process\^
is the execution of an image;
most \*u commands execute as separate processes.
One process may spawn another using the
%fork%
system call,
which duplicates the image of
the original (\c
.I parent\^ )
process.
The new (\c
.I child\^ )
process continues to execute the same program as the parent.
The two images are identical,
except that each program can determine whether it is executing as
parent or child.
Each program may continue execution of the image
or may abandon it by
issuing an
%exec%
system call,
thus initiating execution of another program.
In any case, each process is free to proceed in parallel
with the other,
although the parent most commonly issues a
%wait%
system call to suspend execution until a child terminates (%exit%s).
.DF
.sp 2i
.ce
.bd R 3
\!.bd R 3
Figure 1
.br
.bd R
\!.bd R
.sp 1v
.DE
.P
Figure~1 illustrates these ideas.
\f2Program~A\^\fP is executing (as
.I process~1\^ )
and wishes to run \f2program~B\^\fP.
It
%fork%s
and spawns a child (\c
.I process~2\^ )
that continues to
run \f2program~A\^\fP.
The child abandons \f2A\^\fP by
%exec%ing
\f2B\^\fP,
while the parent goes to sleep until the child
%exit%s.
.P
A child inherits its parent's
.I "open files" .
This mechanism permits processes to share common input streams
in various ways.
In particular, an open file possesses a
.I pointer\^
that indicates a position in the file and
is modified by various operations on the file;
%read%
and
%write%
system calls
copy a requested number of bytes from and to a file,
beginning at the position given by the
current value of the pointer.
As a side effect, the pointer is
incremented by the number of bytes transferred,
yielding the effect of sequential I/O;
%lseek%
can be used to obtain random-access I/O;
it sets the pointer to an absolute
position within the file,
or to a position offset either from the end of the file or from the
current pointer position.
.P
When a process terminates, it can set an eight-bit
.I "exit status\^"
(see \(sc3.4.4)
that is available to its parent.
This code is usually used to indicate success (zero) or
failure (non-zero).
.P
.I Signals\^
indicate the occurrence of events that may have some impact
on a process.
A signal may be sent to a process
by another process,
from the terminal,
or by \*u itself.
A child process inherits its parent's signals.
For most signals,
a process can arrange to be terminated on receipt of a signal,
to ignore it completely,
or to
.I catch\^
it and take appropriate action, as described in \(sc4.4.10.
For example, an
.I interrupt\^
signal may be sent by depressing
an appropriate key (\c
.I del ,
.I break ,
or
.I rubout ).
The action taken depends on the requirements of the specific program
being executed:
.BL 6
.LI
The shell invokes most
commands in such a way that they immediately die when an interrupt
is received.
For example,
the
%pr%
(print)
command
normally dies,
allowing the user to terminate unwanted output.
.LI
The shell \f2itself\^\fP ignores interrupts when reading from the terminal,
because it should continue execution even
when the user terminates a command like
%pr%.
.LI
The editor
%ed%
chooses to
.I catch\^
interrupts so that it can halt its
current action (especially printing) without allowing itself to be terminated.
.LE
.H 1 "SHELL \|BASICS"
.P
The
shell
(i.e., the
%sh%
command)
implements the command language
visible to most \*u users.
It reads input from a terminal or a file and
arranges for the execution of the requested commands.
It is a program written in the C language [9];
it is
.I not\^
part of the operating system,
but is an ordinary user program.
The discussion below is adapted from [2,5,10].
.H 2 "Commands"
.P
A
.I "simple command\^"
is a sequence of non-blank arguments separated by blanks or tabs.
The first argument (numbered \f2zero\^\fP\^) usually specifies
the name of the command to be executed;
any remaining arguments, with a few exceptions, are passed as
arguments to that command.
A command may be as simple as:
.CW
who
.CN
which prints the login names of users who are currently logged into the
system.
The following line requests the
%pr%
command to print files %a%, %b%, and %c%:
.CW
pr a b c
.CN
.P
If the first argument of a command names a file that is
.I executable\^ \*F
.FS
As indicated by an appropriate set of permission bits
associated with that file.
.FE
and is actually a compiled program,
the shell (as parent) spawns a new (child) process that immediately
executes that program.
If the file is marked as being executable,
but is not a compiled program, it is assumed to be
a
shell procedure,
i.e., a file of ordinary text containing
shell command lines, as well as possibly
lines meant to be read by other programs.
In this case, the shell spawns another instance of itself (a
.I sub-shell )
to read the file
and execute the commands included in it.
The shell
%fork%s
to do this, but no
.I exec\^
call is made.
The following command requests that the on-line
.I "U\s-1NIX\s+1 User's Manual\^"
[5] entries that describe the
%who%
and
%pr%
commands be printed on the terminal
(incidentally, the
%man%
command itself is actually implemented as a shell procedure):
.CW
man who pr
.CN
.P
From the user's viewpoint,
compiled programs and shell procedures are
invoked in exactly the same way.
The shell determines which implementation has been used,
rather than requiring the user to do so.
This preserves
the uniformity of invocation
and the ease of changing the choice of implementation for a given command.
The actions of the shell
in executing any of these commands are illustrated in Figure 1 above.
.H 2 "How \|the \|Shell \|Finds \|Commands"
.P
The shell normally searches for commands in a way that permits
them to be found in three distinct locations in the file structure.
The shell first attempts to use the command name as given;
if this fails, it
prepends the string
%/bin%
to the name,
and, finally,
%/usr/bin%.
The effect is to
search, in order, the current directory,
then the directory
%/bin%,
and
finally,
%/usr/bin%.
For example,
the
%pr%
and
%man%
commands are actually the files
%/bin/pr%
and
%/usr/bin/man%,
respectively.
A more complex path name may be given,
either to locate a file relative to the user's current directory,
or to access a command via an absolute path name.
If a command name \f2as given\^\fP contains a
%/%
(e.g.,
%/bin/sort%
or
\&%../cmd%),
the prepending is
.I not\^
performed.
Instead, a single attempt is made to execute the
unmodified command as named.
.P
This mechanism gives the user a convenient way to execute
public commands
and commands in or
.I near\^
the current directory,
as well as the ability to execute \f2any\^\fP accessible command
regardless of its location in the file structure.
Because the current directory is usually searched first,
anyone can possess a private version of a public command
without affecting other users.
Similarly, the creation of a new public command will not affect
a user who already has a private command with the same name.
The particular sequence of directories searched may be changed by resetting the %PATH%
variable, as described in \(sc3.4.2.
.H 2 "Generation \|of \|Argument \|Lists"
.P
Command arguments are very often file names.
A list of file names can be automatically generated as arguments on
a command line, by specifying a pattern that the shell matches against
the file names in a directory.
.P
Most characters in such a pattern match themselves, but there are also
special meta-characters that may be included in a pattern.
These special characters are: %*%,
which matches any string, including the null string; %?%, which matches
\f2any one character\^\fP; and any sequence of characters
enclosed within %[% and %]%, which matches any \f2one\^\fP of the enclosed
characters.\*F~
.FS
Be warned that square brackets are also used below for another purpose:
in descriptions of commands, they indicate that the enclosed argument
is optional.
See also \(sc5.1 below.
.FE
Inside the brackets, a pair of characters separated by
%-% includes in the set all characters lexically within the inclusive
range of that pair,
so that
%[a-de]% is equivalent to %[abcde]%.
.P
For example,
%*%
matches all file names in the current directory,
%*temp*%
matches all file names containing
%temp%,
%[a-f]*%
matches all file names
that begin with
%a%
through
%f%,
%*.c%
matches all file names ending in
%.c%,
and
%/a1/tf/bin/?%
matches all single-character file names
found in
%/a1/tf/bin%.
This capability saves much typing
and, more importantly,
makes it possible to organize information in large collections
of small files that are named in disciplined ways.
.P
Pattern-matching has some restrictions.
If the first character of a file name
is
a period (%.%),
it can be matched only by an argument that
literally
begins with
a period.
If a pattern does not match any file names, then the pattern
itself is returned as the result of the match, for example:
.CW
echo *.c
.CN
will print:
.CW
*.c
.CN
if the current directory contains no files
ending in %.c%.
.P
Directory names should not contain the characters %*%,
%?%, %[%, or %]%, because this may
cause infinite recursion during pattern matching attempts.\*F~
.FS
This is a bug that may be fixed in the future.
.FE
.H 2 "Shell \|Variables"
.P
The shell has several mechanisms for creating variables.
A variable is a name representing a string value.
Certain
variables are usually referred to as \f2parameters\^\fP; these are
the variables which are normally set only on a command line;
there are \f2positional parameters\^\fP (\(sc3.4.1) and \f2keyword parameters\fP
(\(sc4.1).
Other variables are simply names
to which the user or the shell itself may assign string values.
.H 3 "Positional \|Parameters."
When a shell procedure is invoked, the shell implicitly creates
.I "positional parameters" :
the argument in position zero on the command line
(the name of the shell procedure itself)
is called %$0%,
the first argument is called %$1%, and so on.
The
%shift%
command (\(sc4.3)
may be used to access arguments in positions numbered higher than nine.
.P
One can explicitly force values into these positional parameters by using the
%set%
command:
.CW
set abc def ghi
.CN
assigns the string
%abc%
to the first positional parameter (%$1%),
%def%
to the second (%$2%),
and
%ghi%
to the third (%$3%);
%$0% may not be assigned a value in this way\-it always refers to the name
of the shell procedure, or, in the login shell, to the name of the shell.
.H 3 "User-defined \|Variables."
The shell also recognizes alphanumeric variables
to which string values may be assigned.
Positional parameters may not appear on the left-hand side of
an assignment statement; they can only be set as described above.
A simple assignment is of the form:
.DS I
\f2name\^\fP%=%\f2string\fP
.DE
Thereafter,
%$%\f2name\^\fP
will yield the value
\f2string\^\fP.
A
.I name\^
is a sequence of letters, digits, and underscores that begins with a letter
or an underscore.
Note that no spaces surround the %=% in an assignment statement.
.P
More than one assignment may appear in an assignment statement, but beware:
\f2the shell performs the assignments from right to left;\^\fP
the following command line results in
the variable %a% acquiring the value %abc%:
.CW
a=$b b=abc
.CN
The following are examples of simple assignments.
\f2Double\^\fP quotes around \f2the right-hand side\fP
allow blanks, tabs, semi-colons, and
new-lines to be included in \f2string\^\fP,
while also allowing \f2variable substitution\^\fP (also
known as \f2parameter substitution\^\fP) to occur; that is,
references to positional parameters and other variable names
that are
prefaced by %$% are replaced by the corresponding values, if any;
\f2single\^\fP quotes inhibit variable substitution:
.CW
MAIL=/usr/mail/gas
echovar="echo $1 $2 $3 $4"
stars=*****
asterisks='$stars'
.CN
The variable %echovar% has as its value the string consisting of the
values of the first four positional parameters, separated by blanks.
No quotes are needed around the string of asterisks being assigned to
%stars%
because pattern matching
(expansion of %*%, %?%, %[%\|.\|.\|.%]%)
does
.I not\^
apply in this context.
Note that the value of %$asterisks% is the literal string %$stars%, \f2not\^\fP
the string %*****%,
because the single quotes inhibited substitution.
.P
In assignments, blanks are not re-interpreted after variable
substitution,
so that the following example results in %$first% and %$second% having
the same value:
.CW
first='a string with embedded blanks'
second=$first
.CN
.P
In accessing the values of variables, one may enclose the variable name
(or digit, in positional parameters)
in braces %{}% to delimit the variable name from any following string.
In particular, if the character immediately following the name is a letter,
digit, or underscore (digit only for positional parameters),
then the braces are \f2required\^\fP:
.CW
a='This is a string'
echo "${a}ent test of variables"
.CN
.P
The following variables are used
by the shell.
Some of them are set by the shell, and all of them can be re-set by the user:
.VL 11 3
.LI %HOME%
is initialized by the
%login%
program to the name of the user's
.I "login directory" ,
i.e., the directory that becomes the current directory upon
completion of a login;
%cd% without arguments
uses %$HOME% as the directory to switch to.
Using this variable helps one
to keep full path names out of shell procedures.
This is of great benefit when path names are changed, either to balance
disk loads or to reflect administrative changes.
.LI %IFS%
is the variable that specifies which characters are
.I "internal field separators" .
These are the characters the shell uses
during blank interpretation.
(If you want to parse some delimiter-separated data
easily, you can set %IFS% to include that delimiter.)~
The shell initially sets %IFS% to include the blank, tab, and new-line
characters.
.LI %MAIL%
is the path name of a file where your mail is deposited.
If %MAIL% is
set, then the shell checks to see if anything has been added to the file
it names and announces the arrival of new mail every time you return to
command level (e.g., by leaving the editor).
%MAIL% must be set
by the user.
(The presence of mail in the standard mail file is also announced at login, regardless of
whether %MAIL% is set.)~
.LI %PATH%
is the variable that specifies the search path used by the shell
in finding commands.
Its value is an ordered list of directory path names separated by colons.
The shell initializes %PATH% to the list
%:/bin:/usr/bin%
where, by convention, a
.I null\^
character appears in front of
the first colon.
A null anywhere in the path list represents the current
directory.
Thus if you wished to search your current directory last,
rather than first, you would type:
.CW
PATH=/bin:/usr/bin::
.CN
where the two colons together represent a colon followed by a null
followed by a colon, thus naming the current directory.
A user could possess a personal directory of commands
(say, %$HOME/bin%) and
cause it to be searched \f2before\^\fP the other three directories by using:
.CW
PATH=$HOME/bin::/bin:/usr/bin
.CN
The setting of %PATH% is normally done in a user's
%.profile%
file (\(sc3.9).
.LI %PS1%
is the variable that specifies what string is to be used as the
primary
.I prompt\^
string.
If the shell is interactive, it prompts with the value of
%PS1%
when it expects input.
The default value of
%PS1%
is
``%$  %''
(a %$% followed by a blank).
.LI %PS2%
is the variable that specifies the secondary prompt string.
If the shell expects more input when
it
encounters a new-line in its input,
it will prompt with the value of %PS2%.
The default value for this variable is ``%>  %'' (a %>% followed by a
blank).
.LE
.H 3 "Command \|Substitution."
Any command line can be placed within grave accents
(%`%\|.\|.\|.%`%) to
capture the output of the command.
This concept is known as
.I "command substitution" .
The command or commands enclosed between grave accents are
first
executed by the shell and then their output
replaces the whole expression, grave accents and all.
This feature is often combined with shell variables:
.CW
today=`date`
.CN
assigns the string representing the current date to the variable
%today% (e.g., %Tue Nov 27 16:01:09 EST 1979%).
.CW
users=`who | wc -l`
.CN
saves the number of logged-in users in the variable
%users%.
Any command that writes to the standard output can be enclosed
in grave accents.
Grave accents may be nested; the inside sets must be escaped
with %\% (\(sc3.5).
For example:
.CW
logmsg=`echo Your login directory is \`pwd\``
.CN
.P
Shell variables can also be given values indirectly by using the
%read%
command.
The %read%
command
takes a line from the standard input (usually your terminal) and assigns
consecutive words on that line to any variables named:
.CW
read first init last
.CN
will take an input line
of the form:
.CW
G. A. Snyder
.CN
and have the same effect as if you had typed:
.CW
first=G.   init=A.   last=Snyder
.CN
The %read% command
assigns any excess ``words'' to the last variable.
.H 3 "Pre-defined \|Special \|Variables."
\&
.P
.in +\w'~\(rh~\|'u
.ti -\w'~\(rh~\|'u
.I
~\(rh~\|Beginners should skip this section on first reading.
.R
.in -\w'~\(rh~\|'u
.P
Several variables have special meanings;
the following are set \f2only\^\fP by the shell:
.VL 9 3
.LI %$#%
records the number of arguments passed
to the shell,
not counting the name of the shell procedure itself;
%$#% thus yields the number of the highest set positional parameter.
Thus,
%sh x a b c%
sets %$#% to 3.
One of its primary uses is in checking
for the presence of the required number of arguments:
.CW
if test $# -lt 2
then
	echo 'two or more args required'; exit
fi
.CN
.LI %$?%
is the exit status (also referred to as \f2return code,\^\fP \f2exit code,\fP or \f2value\fP)
of the last command executed.
Its value is a decimal string.
Most \*u commands return
%0%
to indicate successful completion.
The shell itself returns the current value of %$?% as \f2its\^\fP exit status.
.LI %$$%
is the process number of the current process.
Because process numbers are unique among all existing processes, this 5-digit
string
is often used to generate unique names for
temporary files
U\s-1NIX\s+1 provides no
mechanism for the automatic creation and deletion of temporary files:
a file exists until it is explicitly removed.
Temporary files are generally undesirable
objects: the \*u pipe mechanism is far superior for many applications.
However, the need for uniquely-named temporary files does occasionally occur.
The following example also illustrates
the recommended practice of creating temporary files in a directory
used only for that purpose:
.CW -t
temp=$HOME/temp/$$	# use current process id
ls > $temp		# to form unique temp file
     \f2commands here, some of which use\^\fP $temp
rm $temp 		# clean up at end
.CN +t
.LI %$!%
is the process number of the last process run in the background (using %&%\^).
Again, this is a 5-digit string.
.LI %$-%
is a string consisting of names of execution flags (\(sc3.9.3,
\(sc4.7) currently turned on in the shell; %$-% might have the
value
%xv%
if you are tracing your output.
.LE
.H 2 "Quoting \|Mechanisms"
.P
Many characters have a special meaning to the shell which is sometimes
necessary to conceal.
Single quotes (%''%) and
double quotes (%""%) surrounding
a string, or backslash (%\%) before a single character, provide this function
in somewhat different ways.
(Grave accents (%``%) are sometimes called \f2back quotes\^\fP, but
are used only for command substitution (\(sc3.4.3) in the shell
and do not hide special meanings of any characters.)~
.P
Within single quotes, all characters (except %'% itself) are taken
literally, with any special meaning removed.
Thus:
.CW
echostuff='echo $? $*; ls * | wc'
.CN
results only in the string %echo $? $*; ls * | wc% being assigned
to the variable %echostuff%, but \f2not\^\fP in any other commands
being executed.
.P
Within double quotes, the special meaning of certain characters
does persist, while all other characters are taken literally.
The characters that retain their special meaning are %$%, %`%, and %"% itself.
Thus, within double quotes, variables are expanded and command
substitution takes place;
however, any commands in a command substitution are not affected by double
quotes outside of the grave accents, so that characters such as
%*% retain their special
meaning.
.P
To hide the special meaning of %$%, %`%, and %"% within double quotes,
you can precede these characters with a backslash (%\%).
Outside of
double quotes, preceding a character with %\% is
equivalent to placing single
quotes around that character.
A %\% followed by a new-line causes that new-line to be ignored, thus
allowing continuation of long command lines.
.H 2 "Redirection \|of \|Input \|and \|Output"
.P
In general, most commands neither know nor care whether their input
(output) is coming from (going to) a terminal or a file.
Thus, a command can be used conveniently either at a terminal or
in a pipeline.
A few commands vary their actions
depending on the nature of their input or output,
either for efficiency's sake,
or to avoid useless actions (such as attempting
random-access I/O on a terminal).
.H 3 "Standard \|Input \|and \|Standard \|Output."
When a command begins execution, it usually expects that
three files are already open: a
.I "standard input" ,
a
.I "standard output" ,
and a
.I "diagnostic (error) output" .
A number called a
.I "file descriptor\^"
is associated with each of these files; by convention,
file descriptor %0% is associated with standard input, file descriptor %1%
with standard output, and file descriptor %2% with diagnostic output.
A child process normally inherits these files from its parent;
all three files are initially connected to the terminal
(%0% to the keyboard, %1% and %2% to the printer or screen).
The shell permits them to
be redirected elsewhere before control is passed to an invoked command.
An argument to the shell of the form
%< %\f2file\^\fP
or
%> %\f2file\^\fP
opens the specified file
as the standard input or output, respectively
(in the case of output, destroying the previous contents of \f2file\^\fP, if any).
An argument of the form
%>> %\f2file\^\fP
directs the standard output to the end of \f2file\^\fP,
thus providing a way to \f2append\^\fP data to it without destroying its existing contents.
In either of the two output cases, the shell
creates
.I file\^
if it does not already exist
(thus %> output% alone on a line creates a zero-length file).
The following appends to file
%log%
the list of users who are currently logged on:
.CW
who >> log
.CN
Such redirection arguments are only subject to variable and command
substitution; neither blank interpretation
or pattern matching of file names occurs after these substitutions;
Thus:
.CW
echo 'this is a test' > *.gal
.CN
and:
.CW
cat < ?
.CN
will produce a one-line file named
%*.gal%
(a most unfortunate name for a file)
and an error message (unless you have a file named
%?%,
which is
also
.I not\^
a wise choice for a file name\-see end of \(sc3.3), respectively.
.H 3 "Diagnostic \|and \|Other \|Outputs."
Diagnostic output from \*u commands is traditionally directed to the
file associated with file descriptor %2%.
(There is often a need for an error output file
that is different from standard output so
that error messages do not get lost down pipelines.)~
One can redirect this
error
output
to a file by immediately prepending
the number of the file descriptor (i.e., %2% in this case)
to either output redirection symbol
(%>% or %>>%).
The following line will
append error messages from the %cc% command to file
%ERRORS%:
.CW
cc testfile.c 2>> ERRORS
.CN
Note that the file descriptor number
must be
prepended
to
the redirection symbol \f2without\^\fP any intervening blanks or tabs; otherwise,
the number will be passed as an argument to the command.
.P
This method may be generalized to allow one to redirect output
associated with any of the first ten file descriptors (numbered %0-9%)
so that, for instance, if %cmd% puts
output on file descriptor %9%, the following line
will capture that output in file
%savedata%:
.CW
cmd 9> savedata
.CN
A command often generates standard output and error output,
and might
even have some other output, perhaps a data file.
In this case, one
can redirect independently all the different outputs.
Suppose
that
%cmd%
directs its
standard output to file descriptor %1%, its error output to file descriptor %2%,
and builds a data file on file descriptor %9%.
The following would direct
each of these three outputs to
a different file:
.CW
cmd > standard   2> error   9> data
.CN
.P
More complex forms of input/output redirection are described in \(sc5.6.
.H 2 "Command \|Lines \|and \|Pipelines"
.P
A sequence of one or more commands separated by
%|% (or %^%)
make up a
.I pipeline .
In a pipeline consisting of more than one command,
each command is run as a separate process
connected to its neighbor(s) by
.I pipes ,
i.e., the \f2output\^\fP of each command (except the last one) becomes the
\f2input\^\fP of the next command in line.
A
.I filter\^
is a command that reads its standard input, transforms it in some way,
then writes it as its standard output.
A pipeline normally consists of a series of filters.
Although the processes in a pipeline are permitted to
execute in parallel,
they are synchronized to the extent
that each program needs to read the output of its predecessor.
Many commands operate on individual lines of text,
reading a line, processing it, writing it out, and looping back for more input.
Some must read larger amounts of data before producing output;
%sort%
is an example of the extreme case that requires all input to be read before
any output is produced.
.P
The following is an example of a typical pipeline:
%nroff%
is a text formatter whose output may contain reverse line motions;
%col%
converts these motions to a form that can be
printed on a terminal lacking reverse-motion capability;
%greek%
is used to adapt the output to a specific terminal, here specified by
%-Thp%.
The flag
%-cm%
indicates one of the commonly used formatting
options, and
%text%
is the name of the file to be formatted:
.CW
nroff -cm text | col | greek -Thp
.CN
.H 2 "Examples"
.P
The following examples illustrate the
variety of effects that can be obtained by combining a few commands
in the ways described above.
It may be helpful to try these examples at a terminal:
.br
.ne 4v
.BL 6
.LI
%who%
.br
Print (on the terminal) the list of logged-in users.
.LI
%who >> log%
.br
Append the list of logged-in users to the end of file
%log%.
.LI
%who | wc -l%
.br
Print the number of logged-in users.
(The argument to %wc% is
.I "minus ell" .)~
.LI
%who | pr%
.br
Print a paginated list of logged-in users.
.LI
%who | sort%
.br
Print an alphabetized list of logged-in users.
.LI
%who | grep pw%
.br
Print the list of logged-in users whose login names contain
the string
%pw%.
.LI
%who | grep pw | sort | pr%
.br
Print an alphabetized, paginated list of logged-in users
whose login names contain
the string
%pw%.
.LI
%{ date; who | wc -l; } >> log%
.br
Append (to
file
%log%)
the
current date followed by the count of logged-in users.
.LI
%who | sed 's/ .*//' | sort | uniq -d%
.br
Print only the login names of all users who are logged in more than once.
.LE
.P
The
%who%
command
does not
.I "by itself\^"
provide options to yield all these results\-they are obtained
by combining
%who%
with other commands.
Note that
%who%
just serves as the data source in these examples.
As an exercise, replace
%who |%
by
%< /etc/passwd%
in the above examples
to see how a file can be used as a data source in the same way.
Notice that redirection arguments may appear anywhere on the
command line.
.H 2 "Changing \|the \|State \|of \|the \|Shell \|and \|the \|%.profile% \|File"
.P
The state of a given instance of the shell
includes the values of positional parameters (\(sc3.4.1), user-defined
variables (\(sc3.4.2), environment variables (\(sc3.4.3), modes of execution
(\(sc4.7) and the current working directory.
.P
The state of a shell may be altered in various ways.
These include the %cd% command, several flags that can be
set by the user, and a file in one's login directory called %.profile%
that is treated specially by the shell.
.H 3 "%Cd%."
The
%cd%
command
changes the current directory to the one specified as its argument.
This can (and should) be used to change to
a convenient place
in the directory structure;
%cd%
is often combined with
%()%
to cause a sub-shell to change to
a different directory and execute some commands
without affecting the original shell.
The first sequence below extracts the component files of the archive file
%/a1/tf/q.a%
and places them in whatever directory is the current one;
the second places them in directory
%/a1/tf%:
.CW
ar x /a1/tf/q.a
(cd /a1/tf; ar x q.a)
.CN
.P
.H 3 "The \|%.profile% \|File."
When you log in,
the shell is invoked
to read your commands.
First, however, the shell checks to see if a file
named
%/etc/profile%
exists on your \*u system, and if it does, commands are read from it;
%/etc/profile%
is used by system administrators to set up
variables needed by \f2all\^\fP users.
Type:
.CW
cat /etc/profile
.CN
to see what your system administrator has already done
for you.
After this, the shell
proceeds to see if you have a
file named
\&%.profile%
in your login directory.
If so, commands are read and executed from
it.
For a sample
\&%.profile%,
see
.I profile (5).
Finally, the shell is ready to read commands from your
standard input\-usually
the terminal.
.H 3 "Execution \|Flags: \|%set%."
The
%set%
command provides the capability of
altering several aspects of the behavior of the shell
by setting certain \f2shell flags\^\fP.
In particular, the %x% and %v% flags may be useful from the terminal.
Flags may be %set% by typing, for example:
.CW
set -xv
.CN
(to turn on flags
%x% and %v%).
The same flags may be turned \f2off\^\fP by typing:
.CW
set +xv
.CN
.P
These two flags have the following meaning:
.VL 9 3
.LI %-v%
Input lines are printed as they are read by the shell.
This flag is particularly
useful for isolating syntax errors.
The commands on each input line are executed after
that input line is printed.
.LI %-x%
Commands and their arguments are printed as they are executed.
(Shell control commands,
such as
%for%,
%while%,
etc., are not printed, however.)~
Note that %-x% causes a trace of \f2only\^\fP those commands
that are actually executed, whereas %-v% prints each line of
input until a syntax error is detected.
.LE
.P
The %set% command
is also used to set these and other
flags within shell procedures (see \(sc4.7).
