When executing files from the directory they are stored in, type ./filename
The file downloadable with the book called my_name, has an error on line 22. It should be else, not elif.
The cd_db file, in the list_tracks() procedure, inside the inside else clause, has { }. Remove the { and } and the program should execute.
Chapter Outline
Shell Programming
What is a Shell?
Pipes and RedirectionRedirecting Output
The Shell as a Programming Language
Redirecting Input
PipesInteractive Programs
Shell Syntax
Creating a Script
Making a Script ExecutableVariables
Putting It All TogetherQuoting
ConditionsHow it Works
Environment Variables
Parameter VariablesHow It Works
The test, or []Command
Functions
Control Structures
elifHow It Works
A Problem with VariablesHow It Works
while
How It WorksHow It Works
until
caseHow It Works
Lists
How It Works
How It worksThe AND List
Statement Blocks
How It Works
The OR List
How It WorksHow It Works
Commands
How It Worksbreak
Command Execution
The : Command
continue
The . Command
echo
eval
exec
exit n
export
expr
printf
return
set
shift
trapHow It Works
unsetArithmetic Expansion
Here Documents
Parameter ExpansionHow It Works
How It Works
Debugging ScriptsRequirements
Summary
DesignNotes
Lecture Notes
Shell Programming
The shell has similarities to the DOS command processor Command.com (actually Dos was design as a poor copy of UNIX shell), it's actually much more powerful, really a programming language in its own right.
A shell is always available on even the most basic UNIX installation. You have to go through the shell to get other programs to run. You can write programs using the shell. You use the shell to administrate your UNIX system. For example:
ls -al | more
is a short shell program to get a long listing of the present directory and route the output through the more command.What is a Shell?
A shell is a program that acts as the interface between you and the UNIX system, allowing you to enter commands for the operating system to execute.
![]()
Here are some common shells.
![]()
Pipes and Redirection
Pipes connect processes together. The input and output of UNIX programs can be redirected.
Redirecting Output
The > operator is used to redirect output of a program. For example:
ls -l > lsoutput.txt
redirects the output of the list command from the screen to the file lsoutput.txt.To append to a file, use the >> operator.
ps >> lsoutput.txt
Redirecting Input
You redirect input by using the < operator. For example:
more < killout.txt
Pipes
We can connect processes together using the pipe operator ( | ). For example, the following program means run the ps program, sort its output, and save it in the file pssort.out
ps | sort > pssort.out
The sort command will sort the list of words in a textfile into alphbetical order according to the ASCII code set character order.The Shell as a Programming Language
You can type in a sequence of commands and allow the shell to execute them interactively, or youu can sotre these commands in a file which you can invoke as a program.
Interactive Programs
A quick way of trying out small code fragments is to just type in the shell script on the command line. Here is a shell program to compile only files that contain the string POSIX.
![]()
Creating a Script
To create a shell script first use a text editor to create a file containing the commands. For example, type the following commands and save them as first.sh
![]()
Note: commands start with a #.
The line
#!/bin/sh
is special and tells the system to use the /bin/sh program to execute this program.The command
exit 0
Causes the script program to exit and return a value of 0, which means there were not errors.Making a Script Executable
There are two ways to execute the script. 1) invoke the shell with the name of the script file as a parameter, thus:
/bin/sh first.sh
Or 2) change the mode of the script to executable and then after execute it by just typing its name.chmod +x first.sh
Actually, you may need to type:
first.sh./first.sh
to make the file execute unles the path variable has your directory in it.Shell Syntax
The modern UNIX shell can be used to write quite large, structured programs.
Variables
Variables are generally created when you first use them. By default, all variables are considered and stored as strings. Variable names are case sensitive.
![]()
Quoting
Normally, parameters are separated by white space, such as a space. Single quot marks can be used to enclose values containing space(s). Type the following into a file called quot.sh
![]()
make sure to make it executable by typing the command:
< chmod a+x quot.sh
The results of executing the file is:![]()
How It Works
The variable myvar is created and assigned the string Hi there. The content of the variable is displyed using the echo $. Double quotes don't effect echoing the value. Single quotes and backslash do.
Environment Variables
When a shell starts, some variables are initialized from values in the environment. Here is a sample of some of them.
![]()
Parameter Variables
If your script is invoked with parameters, some additional variables are created.
![]()
The following shows the difference between using the variable $* and $@
![]()
notice that the first line of the above has a space between the firsr ' and the second '.
Now try your hand at typing a shell script
Carefully type the following into a file called: try_variables
![]()
make sure to make it executable by typing the command:
< chmod a+x try_variables
Execute the file with parameters by typing:try_variables foo bar baz
The results of executing the file is:![]()
How It Works
It creates the variable salutation, displays its value, and some parameter variables.
Conditions
All programming languages have the ability to test conditions and perform different actions based on those conditions. A shell script can test the exit code of any command.
The test, or []Command
Here is how to check for the existance of the file fred.c using the test and using the [] command.
![]()
You can even place the then on the same line as the if, if youu add a semicolon before the word then.
![]()
Here are the conditon types that can be used with the test command. There are string comparison.
![]()
There are arithmetic comparison.
![]()
There are file conditions.
![]()
Control Structures
The shell has a set of control structures.
if
The if statement is vary similar other programming languages except it ends with a fi.
if condition
thenstatements
elsestatements
fielif
the elif is better known as "else if". It replaces the else part of an if statement with another if statement. You can try it out by using the following script.
#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
if [ $timeofday = "yes" ]
thenecho "Good morning"
elif [ $timeofday = "no" ]; thenecho "Good afternoon"
elseecho "Sorry, $timeofday not recognized. Enter yes or no"
fi
exit 1
exit 0How It Works
The above does a second test on the variable timeofday if it isn't equal to yes.
A Problem with Variables
If a variable is set to null, the statement
if [ $timeofday = "yes" ]
looks likeif [ = "yes" ]
which is illegal. This problem can be fixed by using double quotes around the variable name.if [ "$timeofday" = "yes" ]
.for
The for construct is used for looping through a range of values, which can be any set of strings. The syntax is:
for variable in values
Try out the following script:
dostatements
done#!/bin/sh
When executed, the output should be:
for foo in bar fud 43
doecho $foo
done
exit 0bar
fud
43How It Works
The above example creates the variable foo and assigns it a different value each time around the for loop.
How It Works
Here is another script which uses the $(command) syntax to expand a list to chap3.txt, chap4.txt, and chap5.txt and print the files.
#!/bin/sh
for file in $(ls chap[345].txt); dolpr $file
donewhile
While loops will loop as long as some condition exist. OF course something in the body statements of the loop should eventually change the condition and cause the loop to exit. Here is the while loop syntax.
while condition do
Here is a whil loop that loops 20 times.statements
done#!/bin/sh
foo=1
while [ "$foo" -le 20 ]
doecho "Here we go again"
done
foo=$(($foo+1))
exit 0How It Works
The above script uses the [ ] command to test foo for <= the value 20. The line
foo=$(($foo+1))
increments the value of foo each time the loop executes..until
The until statement loops until a condition becomes true! Its syntax is:
until condition
Here is a script using until.
dostatements
done#!/bin/sh
until who | grep "$1" > /dev/null
dosleep 60
done
# now ring the bell and announce the expected user.
echo -e \\a
echo "**** $1 has just loogged in ****"
exit 0case
The case statement allows the testing of a variable for more then one value. The case statement ends with the word esac. Its syntax is:
case variable in
Here is a sample script using a case statement:pattern [ | pattern] ...) statements;;
esac
pattern [ | pattern] ...) statements;;
...#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
case "$timeofday" in"yes") echo "Good Morning";;
esac
"no" ) echo "Good Afternoon";;
"y" ) echo "Good Morning";;
"n" ) echo "Good Afternoon";;
* ) echo "Soory, answer not recognized";;
exit 0How It Works
The value in the varaible timeofday is compared to various strings. When a match is made, the associated echo command is executed.
Here is a case where multiple strings are tested at a time, to do the some action.
case "$timeofday" in
"yes" | "y" | "yes" | "YES" ) echo "good Morning";;
esac
"n"* | "N"* ) <echo "Good Afternoon";;
* ) < echo "Sorry, answer not recognized";;How It Works
The above has sever strings tested for each possible statement.
Here is a case statement that executes multiple statements for each case.
case "$timeofday" in
"yes" | "y" | "Yes" | "YES" )
esacecho "Good Morning"
[nN]*)
echo "Up bright and early this morning"
;;echo "Good Afternoon"
*)
;;echo "Sorry, answer not recognized"
echo "Please answer yes or noo"
exit 1
;;How It Works
When a match is found to the variable value of timeofday, all the statements up to the ;; are executed.
Lists
To test for multiple conditions, we can use nested if or if/elif.
The AND List
Alolows us to execute a series of command. Each command is only execute if the previous commands have succeeded. An AND list joins conditions by using &&.
statement1 && statement2 && statement3 && ...
Her is a sample AND list:#!/bin/sh
touch fine_one
rm -f file_two
if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there"
thenecho "in if"
elseecho "in else"
fi
exit 0How It Works
The touch command creates an empty file. the rm come remove a file. So, before we start, file_one exists and file_two doesn't. The AND list finds the file_one, and echos the word hello, but it doesn't find the file file_two. Therefore the overall if fails and the else clause is executed.
The OR List
The OR list construct allows us to execute a series of commands until one succeeds!
statement1 || statement2 || statement3 || ...
Here is a sample Or listrm -f file_one
if [ -f file_one ] || echo "hello" || echo " there"
thenecho "in if"
elseecho "in else"
fi
exit 0How It Works
The above script removes the file file_one, then test for and fails to find the file_one, but does successfully echo hello. It then executes the then statement echoing in if.
Statement Blocks
Multiple statements can be placed inside of { } to make a statement block.
Functions
You can define functions inthe shell. The syntax is:
function_name () {
Here is a sample function and its execution.statements
}#!/bin/sh
foo() {echo "Function foo is executing"
}
echo "script starting"
foo
echo "script ended"
exit 0How It Works
When the above script runs, it defines the funcion foo, then script echos script starting, then it runs the functions foo which echos Function foo is executing, then it echo script ended.
Here is another sample script with a function in it. Save it as my_name
#!/bin/sh
yes_or_no() {echo "Parameters are $*"
}
while true
doecho -n "Enter yes or no"
done
read x
case "$x" iny | yes ) return 0;;
esac
n | no ) return 1;;
* ) echo "Answer yes or no"
echo "Original parameters are $*"
if yes_or_no "IS your naem $1"
thenecho "Hi $1"
elseecho "Never mind"
fi
exit 0How It Works
When my_name is execute with the statement:
my_name Rick and Neil
. gives the output of:Original parameters are Rick and Neil
Parameters are Is your name Rick
Enter yes or no
no
Never mindCommands
You can execute normal command and built-in commands from a shell script. Built-in commands are defined and only run inside of the script.
break
It is used to escape from an enclosing for, while or until loop before the controlling condition has been met.
The : Command
The colon command is a null command. It can be used for an alias for true..
continue
The continue command makes the enclosing for, while, or until loop continue at the next iteration.
The . Command
The dot command executes the command in the current shell:
. shell_script
.echo
The echo command simply outputs a string to the standard output device followed by a newline character.
eval
The eval command evaluates arguments and give s the results.
exec
The exec command can replace the current shell with a different program. It can also modify the current file descriptors.
exit n
The exit command causes the script to exit with exit code n. An exit code of 0 means success. Here are some other codes.
![]()
export
The export command makes the variable named as its parameter available in subshells.
expr
The expr command evaluates its arguments as an expression.
x = `expr $x + 1`
Here are some of its expression evaluations![]()
printf
The printf command is only available in more recent shells. It works similar to the echo command. Its general form is:
printf "format string" parameter1 parameter2 ...
Here are some characters and format specifiers.
![]()
return
The return command causes functions to return. It can have a value parameter which it returns.
set
The set command sets the parameter variables for the shell.
shift
The shift command moves all the parameters variables down by one, so $2 becomes $1, $3 becomes $2, and so on.
trap
The trap command is used for secifying the actions to take on receipt of signals. It syntax is:
trap command signal
Here are some of the signals.![]()
How It Works
The try it out section has you type in a shell script to test the trap command. It creates a file and keeps saying that it exists until youu cause a control-C interrupt. It does it all again.
unset
The unset command removes variables or functions from the environment.
Command Execution
The result of $(command) is simply the output string from the command, which is then available to the script.
Arithmetic Expansion
The $((...)) is a better alternative to the expr command, which allows simple arithmetic commands to be processed.
x=$(($x+1))
Parameter Expansion
Using { } around a variable to protect it against expansion.
#!/bin/sh
Here are some of the parameter expansion
for i in 1 2
domy_secret_process ${i}_tmp
done![]()
How It Works
The try it out exercise uses parameter expansion to demonstrate how parameter expansion works.
Here Documents
A here document is a special way of passing input to a command from a shell script. The document starts and ends with the same leader after <<. For example:
#!/bin/sh
cat < this is a here
document
!FUNKY!How It Works
It executes the here document as if it were input commands.
Debugging Scripts
When an error occurs in a script, the shell prints out the line number with an error. You can use the set command to set various shell option. Here are some of them.
![]()
Putting It All Together
The rest of this chapter is about designing a CD database application.
Requirements
The system should store basic information about each CD, search for CDs, and update or add new CDs.
Design
The three requirements--updating, searching and displaying the CD data--suggest that a simple menu willbe adequate. Here is the example titles file.
![]()
Here is the associated track file.
![]()
Notes
The code for the CD database is included in the try it out section. The trap command allows the user to use Ctrl-C.
Summary
By the time you enter the CD database application, you will know that programs can be written using just the shell language. The shell is used for much of Linux system administration.
CS 248 - UNIX Programming Web Site Menu
Information | Syllabus | Schedule | Online "Lectures" | Projects | Quizzes | Web Board
Copyright © 2001 by James L. Fuller, all rights reserved.