-------------------------------------------------------------------
Copyright © 2007 Richard J. Gaydos.
-------------------------------------------------------------------
CIS 3735 Chapter 10 The Bourne Shell
-------------------------------------------------------------------
2 Main Uses of a Shell
1. Command Interpreter
2. High-Level Programming Language for Shell Scripts
-------------------------------------------------------------------
Shell Script - File of Commands to be executed by the Shell
To Run a Shell Script: filename
File MUST be EXECUTABLE to run: chmod u+x filename
./filename Tells the Shell to look in the WORKING Directory for
the Script, rather than the normal paths for
executables
The variable $PATH contains the path list
Use setenv PATH newpath to change
Example:
echo $PATH shows
/usr/bin:/usr/local/bin:/usr/dt/bin:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/ccs/
bin:.:/usr/ucb:/usr/local/X11/bin:/usr/local/teTeX/bin
setenv PATH ~:$PATH
echo $PATH shows
~:/usr/bin:/usr/local/bin:/usr/dt/bin:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/cc
s/bin:.:/usr/ucb:/usr/local/X11/bin:/usr/local/teTeX/bin
making your HOME directory the first directory that is searched for a
command
-------------------------------------------------------------------
Example
man echo "Hello there"
Remember u+x
-------------------------------------------------------------------
Command Separators and Grouping
1. NEWLINE or ; Separate commands
Example: a; b; c
2. \ At end of line --> Continue Command on NEXT line
Example: cat a b \
c same as cat a b c
3. | Pipe
Example: zcat small.Z | more
4. & Run Command in Background
Example: a & a runs in background
5. ( )
Subshell
Example: (a ; b) & c
Forks (creates) a process for a ; b
-------------------------------------------------------------------
Job Control - Developed in C Shell, but ...
Bourne has utility jsh
More on Job Control in C Shell Chapter
-------------------------------------------------------------------
Standard Error
Defaults to Terminal, like Standard Output
1> filename Redirect Standard Output
2> filename Redirect Standard Error
Example
Assuming loop.cc exists in your current directory and
loop.dd does NOT
cat loop.cc loop.dd 1> good 2> bad
then loop.cc will be copied to good and
loop.dd error message will go to bad
Example
2>&1 Makes 2 a DUPLICATE of 1, so
BOTH go to the SAME place
-------------------------------------------------------------------
Process - A Unit of Work that can be Identified (PID - Process ID)
and Tracked (PCB - Process Control Block)
A process is USUALLY created EACH TIME you execute a command or
script
There is a HIERARCHICAL Structure to Processes:
Supervisor gets PID 1
Supervisor forks (creates) getty processes for each terminal
so you can log in and use a shell
-------------------------------------------------------------------
Execute a Command:
Parent FORKS a child, then Parent SLEEPS
unless 1. & = Background
2. Built-ins (p. 337)
-------------------------------------------------------------------
Variables in a process are LOCAL
-------------------------------------------------------------------
Process IDs
Use ps -l to get info on processes, including PPID,
Parent’s PID
-------------------------------------------------------------------
Invoking a Shell Script
1. Just enter filename
The Shell forks a duplicate shell (subshell)
THIS subshell tries to execute the script as a COMMAND
If UNSUCCESSFUL, it runs the commands IN the file
Note: You need READ and EXECUTE permission
2. Enter . filename to run the script in the SAME shell
Note: You only need READ permission on our system.
Some systems need read AND execute permissions.
3. Enter sh filename
The Shell forks a duplicate shell (subshell)
THIS subshell executes the commands IN the file
Note: You only need READ permission
-------------------------------------------------------------------
If the FIRST TWO Characters of the Shell Script are #!
you specify a PATH to the SHELL that should run the script
Example: #! /usr/bin/sh for Bourne Shell
Default on our system:
If the FIRST Character of the Shell Script is # and the
SECOND Character is NOT an ! THEN
the Bourne Shell will be used to run the script
-------------------------------------------------------------------
Comments in a Script
Line begins with # (Except the FIRST Line, see previous)
You MUST use MY comment box!!
-------------------------------------------------------------------
Shell Variables
1. Shell Variables
A. Keyword
HOME: Your Home Directory
PATH: What Directories the Shell searches for a
command
B. Special
$? and $#, for examples (More later)
2. User-Created Variables - Programmer creates them
-------------------------------------------------------------------
Note: Variables hold STRINGS
Note: To use variables as NUMBERS, use expr command
Note: You can set variables in .profile
-------------------------------------------------------------------
User-Created Variables - use Assignment Statement
Variable=expression VERY IMPORTANT RULE: NO Spaces around =
Examples
Person=rick Output Reason
echo Person Person No $
echo $Person rick $ allows substitution
echo "$Person xx" rick xx Double Quotes ALLOW
substitution AND
Preserve SPACING
echo '$Person xx' $Person xx Single Quotes SUPPRESS
substitution AND
Preserve SPACING
echo ‘$Person xx’ ‘$rick xx’ Word Smart Quotes are NOT
special characters in UNIX
echo \$Person xx $Person xx Backslash SUPPRESSES substitution
Example
FullName="Rick Gaydos"
echo $FullName Rick Gaydos
echo "$FullName" Rick Gaydos
Example
Files=rick*
echo "$Files" rick*
echo $Files rick.txt rick.c rickgaydos
-------------------------------------------------------------------
Turning Off Variables
1. variable= Sets VALUE OF Variable to NULL
2. unset variable Variable HAS NO VALUE
-------------------------------------------------------------------
Readonly Command
Example
Person=rick
echo $Person See rick
readonly Person
Person=axl See Person: is readonly
To get a List of readonly variables: Enter readonly
-------------------------------------------------------------------
export Command - Globalizes specified variables - ONE-way
communication
Similar to Call by Value in C++
Example 1 - NO use of export
Script testit Script subtest
cheese=american echo "subtest 1: $cheese"
echo "testit 1: $cheese" cheese=swiss
subtest echo "subtest 2: $cheese"
echo "testit 2: $cheese"
The Output:
testit 1: american
subtest 1:
subtest 2: swiss
testit 2: american
Example 2 - USING export
Script testit Script subtest
export cheese
cheese=american echo "subtest 1: $cheese"
echo "testit 1: $cheese" cheese=swiss
subtest echo "subtest 2: $cheese"
echo "testit 2: $cheese"
The Output:
testit 1: american
subtest 1: american
subtest 2: swiss
testit 2: american
-------------------------------------------------------------------
read Command - Read a line into variables, one word per variable,
except LAST variable gets rest of the line
Example
echo "Enter a sentence: \c"
read word1 word2 word3
echo $word1
echo $word2
echo $word3
The output, assuming you type Here are some words
Here
are
some words
-------------------------------------------------------------------
Note: \c suppresses NEWLINE
-------------------------------------------------------------------
Command Substitution - The output of the Command goes to the
Variable
variable=`command`
Example
directory=`pwd`
echo "You are using the $directory directory"
The output
You are using the /.../.../... directory
-------------------------------------------------------------------
Keyword Shell Variables
HOME Your working directory when you log in
PATH Specify directories in the order the Shell is to search
them
Example
PATH=/usr/ucb:/usr/bin:/usr/sbin
export PATH
MAIL Name of the file that holds your mail
Usually, /var/mail/loginname
MAILPATH List of filenames, separated by :, that if modified
(you receive mail), you get a prompt
(specified after a %)
Example
MAILPATH=/var/mail/rick%Rick has New Mail
MAILCHECK How often (in seconds) the Shell is to Check for new
mail
Note: The default is 600 (10 minutes)
Note: 0 means check before each prompt
PS1 Holds the Shell Prompt
Example
PS1="`hostname`: " to get cis: as a prompt
PS2 Holds Secondary Prompt (If a "command ... ends
without ")
Note: The default is >
Example
PS2="More is needed: "
IFS Internal Field Separator
Note: Blank or tab separates fields, can add more
Example
IFS=:
CDPATH If NOT set, cd name searches WORKING Directory for
name
If SET, the directories given are searched
Example
CDPATH=:dir:dir:...
Note: The colon at the beginning implies search the
WORKING Directory FIRST
TZ Time Zone, TZ=zzzHddd, where
zzz is Name of Time Zone
H is number of hours difference from GMT
ddd is Name of Local Daylight Savings Time Zone
Example
TZ=EST5EDT
-------------------------------------------------------------------
Running .profile with the DOT . command, . .profile
The extra DOT runs the script as PART OF the CURRENT Shell
If you entered .profile while a Shell is RUNNING, the Shell would
FORK, and the variables you set in the .profile would be in
effect only in THAT SUBSHELL ! ! !
-------------------------------------------------------------------
Readonly Shell Variables
$0 The Name of the Command you used to call a program
$1-$9 First 9 Command line arguments
$* ALL Command line arguments:
$@ Like, $*, except quotes arguments individually
IN a Double Quote String:
"$@" is same as "arg" "arg" "arg"
"$*" is same as "arg arg arg arg"
$# Number of arguments on the command line
$$ PID of current process
$! PID of last process you ran in the background
$? Condition Code of last process
-------------------------------------------------------------------
The shift Command
Moves 10th argument to 9th
9th argument to 8th
...
1st argument UNAVAILABLE
Note: There is NO way to automatically UNSHIFT
-------------------------------------------------------------------
The set Command
set arg1 arg2 arg3 ...
Used in scripts, replaces the values of $1, $2, $3, ... with
arg1, arg2, ...
-------------------------------------------------------------------
The exit Command
exit ConditionCode
Sets the $? variable to ConditionCode and exits the script
-------------------------------------------------------------------
Control-Flow Commands
-------------------------------------------------------------------
If Then Else
if test
then
commands
else
commands
fi
-------------------------------------------------------------------
Example
if test $# = 0
or
if [ $# = 0 ]
Note: Brackets MUST HAVE spaces or tabs on either side of each of them
-------------------------------------------------------------------
test Command
test expression
or
[ expression ]
Also
[ exp -a exp ] Means AND
or
[ exp -o exp ] Means OR
-------------------------------------------------------------------
test Command string tests
Criteria Is TRUE if ...
string string is not NULL
-n string string has a length greater than zero
-z string string has a length of zero
string1 = string2 equal strings
string1 != string2 NOT equal strings
-------------------------------------------------------------------
test Command integer tests
Criteria Is TRUE if ...
int1 relop int2 int1 ? int2
from -gt > -lt <
-ge >= -le <=
-eq = -ne not =
-------------------------------------------------------------------
test Command file tests
Criteria Is TRUE if ...
-b filename filename exists and is a block special file
-c filename filename exists and is a character special file
-d filename filename exists and is a directory
-f filename filename exists and is an ordinary file
-h filename filename exists and is a symbolic link
-g filename filename exists and its set group id bit is set
-u filename filename exists and its set user ID bit is set
-k filename filename exists and its sticky bit is set
-p filename filename exists and is a named pipe
-r filename filename exists and you have read access to it
-w filename filename exists and you have write access to it
-x filename filename exists and you have execute access to it
-s filename filename exists and has a size > zero bytes
-------------------------------------------------------------------
test Command file-descriptor test
Criteria Is TRUE if ...
-t file-descriptor the open file file-descriptor is associated
with a terminal
If file-descriptor is left off, 1 (standard output) is assumed.
Note: 0 = standard input
2 = standard error
-------------------------------------------------------------------
if then elif
if test
then
commands
elif test
then
commands
elif test
then
commands
else
commands
fi
-------------------------------------------------------------------
For In
for loop-index in argument-list
do
commands
done
Example - note the absence of $ in front of the variable fruit
for fruit in apples oranges bananas
do
echo $fruit
done
The output would be
apples
oranges
bananas
-------------------------------------------------------------------
for Statement
for loop-index
do
commands
done
Example: call this script test
for args <--- Implies args in "$@"
do
echo $args
done
If you call the script with test a b c
The output would be
a
b
c
-------------------------------------------------------------------
while Statement
while test
do
commands
done
-------------------------------------------------------------------
Example
Number=0
while [ $Number -lt 10 ]
do
echo "$Number\c"
Number=`expr $Number + 1`
done
echo $Number
produces the output
012345678910
-------------------------------------------------------------------
until Statement
until test
do
commands
done
-------------------------------------------------------------------
Example
secretname=rick
name=noname
echo Try to guess the secret name !
echo
until [ "$name" = "$secretname" ]
do
echo "Your guess: \c"
read name
done
echo Very good
could produce output like
Try to guess the secret name !
Your guess: axl
Your guess: slash
Your guess: rick
Very good
-------------------------------------------------------------------
The break Statement
Transfers control to the statement AFTER done
Get OUT of the loop
-------------------------------------------------------------------
The continue Statement
Transfers control TO the done statement
Just skip the remainder of THIS iteration, but continue the loop
-------------------------------------------------------------------
The case Statement
case test-string in
pattern-1)
commands
;;
pattern-2)
commands
;;
pattern-3)
commands
;;
*)
commands
;;
esac
Example
echo "Enter A, B, or C: \c"
read Letter
case $Letter in
A)
echo You entered A
;;
B)
echo You entered B
;;
C)
echo You entered C
;;
*)
echo You did not enter A, B, or C
;;
esac
-------------------------------------------------------------------
Patter Matches for Case are SIMILAR to an Ambiguous File Reference
Pattern Matches
* Any string of characters
? Any SINGLE character
[...] A character class Examples [ABC], [0-9]
| Alternate choices
-------------------------------------------------------------------
The Here Document - Input to a script WITHIN the script
command <<+
database
+
Note: The delimiters do NOT have to be +, but they must MATCH
Example
grep -i $1 <<+
database
+
Search for first argument in database (-i = IGNORE case)
-------------------------------------------------------------------
The exec Command
1. Run command WITHOUT creating NEW process --> get PARENT’s
variables
exec command arguments
Similar to . (dot) command
2. Redirect standard input, output, error of script
from WITHIN the script
exec < infile All subsequent input comes from infile
exec > outfile All subsequent output goes to outfile
exec 2> errfile All subsequent error output goes to errfile
Note: This redirection can still be on a per-command basis:
command < file or command > file
-------------------------------------------------------------------
Note: /dev/tty can be used as the name of the terminal
-------------------------------------------------------------------
The trap Command
Traps a signal report to a process about a condition
Signal Numbers are stored in /usr/include/sys/signal.h
Signal Number Generating Code
Kill 9 Kill Command with -9 Option
Note: Can NOT be trapped
kill -9 process-id
kills that process-id
Software Termination 15 The Default of the Kill Command
Example Uses of trap
1. trap 15 Traps 15 and exits the script
2. trap '' 15 Traps 15 and does NOTHING
3. trap 'cmd1; cmd2' 15 Traps 15 and Executes cmd1 and cmd2
-------------------------------------------------------------------
Functions
Like scripts, but stored in main memory, rather than a file -->
Quick Access
Preprocessed (Parsed) by shell --> Quick Startup
Executed in SAME shell that called the function
-------------------------------------------------------------------
Functions can be declared in
1. .profile
2. A script you want to use the function in
3. Can be entered from the command line
-------------------------------------------------------------------
Syntax
name ()
{
commands
}
Example
whoson()
{
date
echo users logged in
who
}
-------------------------------------------------------------------
Functions can be "Removed" by unset
-------------------------------------------------------------------
Built-In Commands We Covered
: continue pwd shift. echo read
test ` ` exec readonly trap break
exit return unset cd export set
-------------------------------------------------------------------
Special Characters
newline Start command
; Command separator
( ) Group commands and function
& Run in background
| Pipe
> Redirect standard output
>> Append standard output
< Redirect standard input
<< Here document
* Match any string
? Match one character
[ ] Character class
\ Quote next character
' Quote a string, PREVENT all substitutions
" Quote a string, ALLOW Variable AND Command substitution
` ` Perform Command Substitution
$ Variable
. Execute a command
# Comment
{ } Grouping in a function
: NULL command
-------------------------------------------------------------------