The command processor, the shell,
provides the interface between you and the Unix operating
system kernel.
To determine the current active shell, enter the
ps (process status) command
and observe the shell having the highest process id number:
ps
To determine the default login shell, enter:
grep $USER /etc/passwd
This command may not display the anticipated result on some
Unix systems, such as NeXT workstations, as these systems do not
store the userid information in /etc/passwd.
Shell Features
The shells (command processor) provides the following features:
- Command Line Processing
- Redirection
- Pipes and Filters
- Variable Definition
- Script Processing
We have already discussed command line processing, redirection,
pipes, and filters. It is important
to note that these functions are performed by the shell and not the
Unix operating system kernel.
The remaining two topics, plus
enhanced interactive features of the BASH, Korn, and C Shells are the
subject of this chapter.
First, however, we will present a brief overview of three of the
most commonly used shells:
shell name prompt command to initiate
---------- ------ -------------------
Bourne $ sh
Korn $ ksh
BASH $ bash
C % csh
You can initiate a new shell by invoking the command name of the shell
you would like to use. Say for example, you are using the Korn Shell
and would like to try some of the example exercises for the C shell,
simply enter:
csh
To return to the prior shell (or logoff if you are in the lowest level
shell), press <Ctrl-D> or enter the command exit.
The default shell is typically defined in the file
/etc/password.
The chsh (CHange SHell) command can be used to change the default
logon shell in some Unix environments such as SGI Altix and IBM AIX; this command is
not available on Sun implementations of Unix.
If available, you can use this command by simply entering chsh
Typically you will then be prompted to enter your logon password and then the full
path and filename of the shell you widh to use. For example, to switch to the Korn shell,
you would specify "/bin/ksh". See the "chsh" man page for full details.
Which Shell to Use?
The BASH Shell
The BASH, Bourne-Again Shell,
is a popular shell now found as the default on most Linux systems and Mac OS-X;
unless you have requested another shell, it is the default used on the VT ARC Systems.
This shell is based on the Bourne shell and
includes a variety of interactive features such as command alias and history.
For a summary of BASH commands, see
An A-Z Index of the Linux BASH command line.
When you are using the BASH shell, you can use the "help" command to display
a list of BASH shell commands; entering "help" followed by the name of any of these commands will
display a command usage summary.
The Bourne Shell
The Bourne Shell was developed in
the late 1970's and is still available on almost all Unix systems. Since it is portable,
compact in size, requires minimal resources, and executes rapidly, it is commonly used
for shell scripts. Due to its lack of interactive features, it is not recommended for use
as your logon shell.
For a general reference on the Bourne Shell, see
An Introduction to the Unix Shell
The C Shell
The C Shell was designed to use a C language script
syntax and provide interactive features
such as command alias and history to make it more
suitable for interactive applications than the Bourne shell:
Unfortunately the script language of the C Shell is not
compatible with Bourne, Korn, and BASH Shells.
The Korn Shell
The Korn Shell is compatible with and
includes most of the features of the Bourne shell.
It also includes a variety of interactive features such as command alias and history.
Selection Summary
Since the BASH Shell provides both compatibility with the Bourne shell
and interactive capabilities analogous to those of the Korn and C shells,
it is commonly the shell of choice on the systems where it is
available. If you are already familiar with using either the Bourne, Korn, or
C Shell, you can continue to use your preferred shell on the VT ARC Systems; however, you are
encouraged to try the BASH Shell -- it is the shell provided by default
if you do not specifically request another shell on your ARC application form.
See Differing Features in
"Bash Guide for Beginners"
for a table comparing features of the Bourne, C, Korn, and BASH shells.
No matter which shell you select for interactive applications, you may
wish to use the Bourne shell for writing scripts to maximize their portability
among systems.
Quoting Characters
A variety of keyboard symbols take on special meanings in the Unix shell
environments; see
Unix Special Characters for examples of
some of the most commonly used symbols. The quoting functions are
provided to
enable inclusion of commands within text substitutions or to remove the
significance of special characters. The "echo" and "date" commands
will be used to illustrate how the quoting characters can be put to use.
The "date" command displays the current date and time, e.g., enter:
date
The command "echo" is used to display the contents of a string.
echo 'Here is a text string.'
The primary quoting characters are:
- `
- (back quote or open single
quote which is typically
found as the unshifted equivalent of the ~ key on most keyboards)
executes the enclosed command and substitutes the result of the command.
Enter the following command and observe the results displayed on your
screen:
echo Today is `date`
- \
- (back slash)
removes the special significance of a single character.
echo Today is \`date\`
- '
- (single quote) remove the special significance of all
enclosed characters.
echo 'Today is `date`'
All text included within a pair of single quotes is considered
as a single argument when it is passed to a command or shell script.
- "
- (double quote) remove the special significance of all
enclosed characters except $ (allows variable substitution),
` backquote (allows command
substitution),
! (allows history substitution in the C Shell),
and \ (when it precedes a special character such as
$, ", or \).
echo "Today is `date`"
Now observe the result of issuing the following commands:
echo *
echo \* '*'
echo "*"
Use of the quoting functions will be further illustrated by additional
examples in this chapter.
Shell Variables
Shell variables follow the following naming convention:
- 1-20 characters (alphabetic, numeric, or an underscore).
- First character must be alphabetic or an underscore.
The command 'set' can be used to display shell
variables; use the "unset" command to remove a variable definition.
To display the value of a shell variable, use the echo command and
a dollar sign ($) preceding the name of the variable. For example, to
display the value of the variable TERM, enter:
echo $TERM
Note: Uppercase letters are typically used for the system's environmental variables.
To create a shell variable using one of these shells, simply enter
the name of the variable you would like to create followed by an
equal sign and the text you would like to assign to it. If you would
like to include a blank in the text, enclose the text string in single
or double quotes.
Do not include a blank either prior to or following the equal sign.
Here are some examples illustrating assignment of
shell variables; observe the results displayed
using the echo commands:
t='Today is '
d=`date`
echo $t $d
Use the export command save the variable definition as and environmental variable and
to pass the value of the assigned variable to future processes created by this shell.
For example,
if invoke a second Korn Shell, but have not exported a variable, the
value of the variable will not be avaiable to applications run within
this invocation of the shell.
For example, consider the result of executing the following commands:
x='1+3'
echo $x
ksh
echo $x
exit
export x
ksh
echo $x
ps
exit
Note: Be careful how many times you use the exit command as it may
in logging off from the system. It is recommended that you use the
ps command prior to issuing an exit command or pressing <Ctrl-D>
so that you do not logout inadvertently.
Note: you can create an environmental variable as a single command: for example to create an
environmental variable x having the value '1+3' as above, we could have entered:
export x='1+3'
The "set" command is used to assign a text string
to a C Shell variable.
- set t='today is '
- set d=`date`
- echo $t $d
Environmental Variables
Environmental (keyword) variables are used to define parameters used
by the operating system and the system environmental variables
are typically entered as all upper case names.
Observe the results of entering each of the following commands:
echo $HOME
echo $TERM
env
The environmental variable HOME is defined by the system to be the home directory for each
account; the TERM variable defines the current terminal type. Recall
that we had
previously initialized $TERM as
"vt100".
The env ("printenv" command on some Unix systems)
displays a list of the currently defined environmental variables.
Note: if the "env" command fails to display a list of the environmental variables,
try using the command "printenv" instead.
If you are using the BASH, Bourne, or
Korn Shell, you can change the displayed prompt by
assigning a value to the PS1 environmental variable.
For example, in the Bourne Shell,
to display your home directory followed by two greater than signs (>>)
as the prompt,
enter the following commands:
PS1='>> '
export $PS1
Note: To make these commands effective for future sessions,
include them in the file ".profile" which is executed when you log into
the system.
Note: The character used in the above example is an open single
quote (', an apostrophe). If you do not pair quoting characters
correctly, unexpected results may occur. If you observe only a single
greater than sign when you attempt to assign '>> ' to the PS1
environmental variable, you have not paired your quote marks correctly.
You can terminate entry of this command by pressing <Ctrl-C>.
In the Korn Shell, you can
include the current command number and current directory as part of
the displayed prompt by either entering the following pair of commands or
by including them in the file ".profile" for use by
future login sessions:
PS1='! $PWD>'
export $PS1
By default the C Shell generates the % prompt, but it can be
tailored to your preference. For example, to include the
current directory as part of the C shell prompt, enter:
set prompt="$cwd"%
alias cd 'cd \!* ;set prompt="$cwd"%'
The
alias command
is required when using the C Shell to reset
the prompt when you change into a new directory.
Include this pair of commands in the file ".cshrc" if you would like
to make these definitions available in future invocations of the
C Shell command interpreter.
The PATH variable is used to store a list of directories which are
searched when you issue a command. To display the current value of
the PATH variable, simply enter:
echo $PATH
To add an additional directory (e.g., my_new_directory) to
the value of the PATH variable in the Bourne or Korn shells,
use the following commands:
PATH=$PATH:my_new_directory
export PATH
Do not include spaces prior to or after the equal (=) sign.
Note: By default, the VT ARC systems do not include "." (the current directory) in the
search path as doing so is considered a potential security risk!
If you are using the C shell, use the following command
to add a directory to the PATH variable:
set path=($path my_new_directory)
Note:
The C shell uses both the "path" and "PATH" variables; the
the value of the "PATH" variable is updated
whenever the value of the "path" variable is changed.
To assign a list of items to a variable when using the C Shell,
enclose it in parentheses.
The command "set" is used to assign a value to a C Shell
variable in the local environment;
"setenv" is used to assign a value to a C Shell variable in
the global environment, i.e., the current environment
and all future processes generated from this shell.
The expr command can be used to
evaluate numeric expressions.
For example, consider the results
of entering the following commands:
- counter=5
- expr $counter + 5
- x=`expr 5 + 9 `
- echo $x
Note: You must include spaces between each of the terms and operators
when you use the expr command.
The "let" command can be used with the BASH or
Korn Shell to evaluate expressions and assign the result to a variable.
For example, using either of these shells, observe the results
of entering the following commands:
- let counter=5
- let counter=2*$counter+5
- echo $counter
Note: When using the "let" command, do not include spaces between the variable name and the equal
sign nor following the equal sign.
The "@" command can be used within the C shell to evaluate expressions
and assign the result to a variable.
If you are using the C Shell, observe the result of the following
commands:
- @ counter = 5
- @ counter = 2 * $counter + 5
- echo $counter
- @ counter += 1
- echo $counter
- @ counter ++
- echo $counter
- set d=`date`
- echo $d
- echo $d[3]
- @ d[3] ++
- echo $d[3]
When "@" is used for expression evaluation with the C Shell, you
must include a space before and after the equal sign as well as between
each element which appears on the right side of the expression.
In the last three examples,
$d[3] corresponds to the 3rd element (day of the month) assigned
to the variable "d" by the set command.
Command Alias Applications
The alias command is available in both the BASH, Korn, and C shells to provide
substitution of a command or command string by an alternative name
or abbreviation.
The alias commands illustrated in this section assume use of the Korn
Shell. If you are using the C Shell, substitute a blank space for the
equal sign in the example definitions.
The alias command is not available in the Bourne shell.
The alias command is commonly used to:
- To minimize repetitive typing and thus reduce errors (i.e., create
abbreviations):
alias h=history
- To create your own commands:
alias listdir='find . -type d -print'
- To modify the action of an existing command:
alias ls='ls -F'
- The -i option of the cp, mv, and rm command results in an
interactive prompt being displayed prior to overwriting or removing
each file which would be affected by the command. This option can be
used to provide some protection
from mistakes which would be caused
by accidently
overwriting or removing files. To obtain this protection, include
the following alias definitions in .profile (Korn Shell)
or .login (C Shell -- recall you should substitute a space for the
equal sign in the alias examples).
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'
You will now be asked for confirmation prior to overwriting or removing
an existing file.
If you are using the C Shell and would like
to prevent overwriting files by redirection,
set the "noclobber" variable:
set noclobber
To display a listing of the currently defined aliases, simply enter the
command:
alias
To remove an alias definition,
use the unalias command. For example,
to remove the alias of h for the history command, enter:
unalias h
The C shell contains one alias feature not found in the
Korn Shell: command line substitution.
When using the C Shell, it is possible to substitute the remainder of
the command line at a specific point (variable \!*) within the alias
definition.
Say for example,
you would like to turn off messages while in vi. In the C Shell you
could define the following alias:
alias vi 'mesg n;/usr/ucb/vi \!*; mesg y'
Then, if you were to enter the command "vi my_file", the alias would
first turn off messages, execute the command "/usr/ucb/vi my_file",
and then turn messages back on after you had exited from vi.
Command History & Command Line Editing
The history command enables recall of previous commands for re-execution;
it is not available for use with the Bourne shell.
To recall a prior command, simply press the up arrow key; the down arrow key
can be used to scroll back through the list of previously displayed commands.
To edit the current command line, simply use the right or left arrow keys to move to the appropriate
position in the line. You can insert new characters after the current cursor position by simply typing
the text you wish to enter; use the "Backspace" key to delete the character in front of
the current cursor position.
The BASH Shell keeps a log of previously issued commands in the file
".bash_history". To review a list of previously entered comands, enter: history
You can also use the C Shell History commands described below.
The Korn Shell keeps a log of previously issued commands in the file
".sh_history". To recall a prior command, you must first specify which
editor you would like to use with the command history. To use the vi
editor, you must have first invoked the following command:
set -o vi
You can either enter this command at the system prompt
or, for future logon sessions, include it in the file ".profile".
Now you can use vi commands to edit previous commands.
First press <Esc> to enter vi command mode; a few of
the most commonly used command line editing
keys include:
- k
- recall the previous command. Pressing this key multiple times
allows you to scroll back through previously issued commands.
- l
- (lower case L)
allows you to move the cursor to the right one character at a
time. Of course you can precede the "l" with a number to move the cursor
the specified number of characters to the right.
- h
- allows you to move the cursor to the left one character at a
time. Of course you can precede the "h" with a number to move the cursor
the specified number of characters to the left.
- A
- enter insert mode at the end of the command.
- a
- enter insert mode after the current cursor position.
- i
- enter insert mode in front of the current cursor position.
- I
- (uppercase i) enter insert mode at the beginning of the line.
- r
- replace a single character
Even though the cursor arrow keys may function for you while
using the vi editor, they may not function while
editing the command line.
Thus you need to be familiar with using the "l" key to move the cursor to
the right and the "h" key to move the cursor to the left.
When you are finished editing a command,
you can execute it by pressing the
<Return> key.
If you are using the Korn Shell and would like to try using the C Shell
interactive history features, enter the following command prior to
issuing any to the other commands in this section
(recall that you can return from the C Shell back to the Korn Shell
by pressing <Ctrl-D> or entering the command exit):
csh
To use the C Shell history
capabilities, you must first turn on the history command by assigning
a number to the history variable.
Include the following command in the file
".cshrc" to assign the value 23 to the history variable:
set history=23
You will now have access to the last 23 commands you had
issued. Since Unix systems typically display 24 lines of output, this
allows all of the stored commands to be displayed without scrolling off
the top of the display screen. If you prefer, you can use a value
which is larger or smaller than 23.
The following table illustrates how the C Shell
history command can be used:
- !!
- re-execute the last command
- !vi
- re-execute the last command beginning with "vi"
- !?fred?
- re-execute the last command containing "fred"
- !5
- re-execute command number 5
- !5:s/old_text/new_text
- re-execute command 5 and
substitute "new_text"
for "old_text"
- old_text<caret>new_text
- re-execute
the previous command and
substitute "new_text"
for "old_text". On most keyboards, the <caret>, also known as "hat"
is obtained by pressing
the shift key and then the number six key
the "typewriter" section of the keyboard.
- !-5
- re-execute the fifth previous command
The old_text and new_text in the above examples cannot include
blank spaces.
"!" is pronounced "bang".
Execute the following commands and observe how the history capabilities
enables recall of past commands and minimization of typing:
set history=23
set prompt='\!%'
mkdir xmp
ls -la
!!
ls -F
history
!-2
!cat
Unix Shell Scripts
Unix shell scripts provide a convenient mechanism for simplfing the
execution of complex or repetitive command sequences.
Typically a "#" used within a shell script is used to indicate
a comment; however, if "#" appears as the first character of the first
line, its interpretation is different.
You can begin a script with "#!/bin/sh" to indicate that the
commands contained in the file are to be interpreted as a Bourne Shell
script, #!/bin/csh for a C Shell script,
or #!/bin/ksh for a Korn Shell script.
If "#" appears as the first character of the first line and is not
followed by "!", the results are system dependent, but may
result in the commands within the file being interpreted in the language
of the login shell.
Before a script can be executed, it must be given execute permission.
Use the chmod command to make this file executable by user, group, and
other:
chmod a+x my_script
Shell scripts can include the following capabilities:
- Evaluating Expressions
- Processing Input Arguments
- Conditional Processing
- Looping
Shell scripts provide the following advantages over programming
languages:
- Easy to write and maintain
- Don't need to compile and link
- Shells contain built in commands for fast execution
Numbers and text strings can be passed for use within a script on the
command line following the name of the script when it is used. Each
item passed to the script is known as an argument; blank space are used
as the delimiter between arguements except any information which is
enclosed within qoutes is considered as a single argument.
As an example, suppose we would like to create a shell which would add
the values of two numbers entered on the command line and return the
result. We could do so by creating a file called "add2"
containing the following line:
echo "The sum of $1 and $2 is: `expr $1 + $2`
We could then obtain the sum of 5 and 4
either by entering the command
"sh ./add2 5 4"
or by using the chmod command to make file 'add2'
executable and then entering "add2 5 4".
A second example illustrating how arguments can be passed to a shell
script is contained in the sample file "argtest". This shell first
prints a list of all the arguments which were passed to it and then it
prints a line for each argument it contains.
This file also illustrates use of some of the flow control commands
discussed in
Flow Control.
Observe the results of entering
the following commands:
./argtest
./argtest one two three
./argtest a b c d e f g h i j k l m n o p q r s
The following arguments can be used within the Bourne, C, or Korn Shells:
- $*
- all arguments (alternatively you can also use $argv[*]
or $argv in the C Shell).
- $1...$9
- arguments 1 to 9.
The shift command can be used to access arguments 10 and higher
which are passed to a shell script. When the shift command is executed,
the values associated with the variables $1 through $9 are shifted to
the next lower numbered variable. Thus $1 then has the former value of
$2 and $9 has the value associated with the 10th argument. If the shift
command is issued again, $1 will then have the value
associated with the 3rd argument and $9 will have the value associated
with the 11th argument. The shift command can be repeated until all
arguments are read. Use of the shift command to read all command
line arguments is illustrated in sample file "argtest". Also note
that the shift command reduces the value of the $# Bourne and Korn
shell variable by 1 for each time it is issued.
The following arguments can be used only for the Bourne and Korn Shells:
$# number of arguments.
$? error return code.
$a all arguments on the command line individually quoted.
The following arguments can only be used with the C shell:
$0 name of the program.
$argv number of arguments.
$argv[n] argument n (n is between 1 and 9, $argv[0] is invalid).
$argv[1-n] arguments 1 to n (9 is maximum value for n).
argv[$#argv] the last argument.
The Shells contain the following types of control structures to provide
conditional and loop processing:
- if (expression) command [C Shell]
- if-then structures
- if-then-else structures
- if-then-elseif-else structures
- switch and case structures
- for (loop) structures
- while structures
- until structures [Bourne, Korn, & BASH shells]
- goto statements [C Shell]
- continue statements
- on interrupt (onintr) statements
[C Shell]
The example program "argtest" illustrates use of three of these
structures. Since the first line of this shell begins with "#!/bin/sh",
this shell will be executed using the Bourne Shell.
Following the first line the script assigns initial values to the
variables n and total. A blank line is then printed by the echo
command.
The first control structure is an "if-then" which is used to print a
message if no arguments were included when the command was entered.
The "if-then" conditional begins with a test of the expression
"$# -lt " and ends with the "fi" ("if" spelled backwards)
statement.
If the number of arguments is less than 1, the "then" statements are
executed. In this example, a message is displayed indicating that there
were no command line arguments, a blank line is printed, and the
script is terminated by the "exit" statement.
When there are one or more arguments, the above "if" condition is not
satisfied and the program continues by printing (echo) the list of
arguments passed to the script.
The "if" conditional statement is followed by a "while-do"
structure (terminated by a "done" statement) which indicates that
all of the statements are to be repeated so long as the current value
of $n is less than or equal to the number of command line arguments.
Note that the value of "$n" is incremented by 1 just before the
"done" statement.
Following the "do" statement is a "case" control structure which ends
with the statement "esac" ("case" spelled backwards). This "case"
structure examines the value of "$n". If it is "1", control is
forwarded to the statement beginning with "1)" and
it prints a
message that the value of the first argument is "$1". Similar statements
are included for "$n" in the range 2 through 9. If "$n" is greater than
9, then control is passed to the statements following "*)". Here the
shift command is issued and a message is printed indicating that the
value of the nth argument is equal to "$9" (recall our prior discussion
of the shift command and its effect upon the values associated with the
shell variables $1 through $9).
After all of the arguments have been processed, the script continues
after the done statement by printing a blank line (echo) and then
exits.
This program was written to illustrate use of the "case" control
structure as well as the "while-do" and "if-then" structures. If we
had not been interested in illustrating this control structure,
this script could have been simplified by substituting the following
statements for all of the statements between and including the "case"
and "esac" statements:
echo "Argument $n is: $1"
shift
n=`expr $n + 1`
|