Shell Programming
Creating Shell Scripts: Some Basic Principles
• A script name is arbitrary. Choose names that make it easy to quickly identify file function.
• Use .sh as an extension to denote shell script files.– Example: quarterly_report.sh
• Make #!/bin/sh be the 1st line of your script (she-bang).
• Add comments to your scripts using #. Everything to the right of # is for the benefit of humans.
• Use chmod +x to make the shell script executable.
• To execute in current directory use ./script.sh
Interactive vs. Non-Interactive Scripts• Scripts should be both interactive (accept user input) and non-
interactive (for use with pipes, redirection, cron jobs, …)
• The read statement enables a script to take input from user.
• Positional parameters allow scripts to be non-interactive.
– command line arguments are referred to as $0 (the command name), $1, $2, …
– $# refers to the total number of arguments on the command line
– $* is a string representing all the parameters
An Example Script Interactive Version: echo “Enter pattern to be searched: \c” # \c = no newline
read var1
echo “Enter file to be used: \c”
read var2
echo “Searching for $var1 from file $var2”
grep “$var1” $var2 # quote multiword strings
Non-Interactive Version: echo “Program: $0” # $0 always = script name
echo “The number of arguments specified is $#”
echo “The arguments are $*” # all arguments stored in $*
grep “$1” $2
echo “\nJob Over”
• All scripts have an exit status indicating whether or not the script succeeded or failed.
• Use the exit command to indicate the script status.
• exit values– exit - everything OK, default status is 0– exit 0 - True, meaning everything ran OK– exit n - False, meaning error was encountered (n >
=1)
• The variable $? stores the exit status of the last command.
• The programmer of the script determines success or failure.
The Exit Status of a Script
&& is the logical AND operator that connects 2 commands:
cmd1 && cmd2 means cmd2 is executed if cmd1 succeeds
|| is the logical OR operator that connects 2 commands:
cmd1 || cmd2 means cmd2 is executed if cmd1 fails
Examples:
$ grep ‘manager’ emplist && echo “Pattern found”
# display success message if grep works
$ grep “$1” $2 || { echo “not found”; exit 2; }
# quit if search fails
Making Simple Decisions with 2 Logical Operators
Making Decisions with if-then-else Statements
if command is successfulthen
excute commandsfi
if command is successfulthen
excute commandselse
excute commandsfi
if command is successfulthen
excute commandselif command is successful then
excute commandselse
excute commandsfi
Form 1:
Form 2:
Form 3:
An if-then-else Example
$ pico ifthen.shif grep “^$1[: ]” /etc/passwd # did grep succeed?then
echo “Pattern found – Job over” # yes, grep workedelse
echo “Pattern not found” # no, grep failedfi
$ chmod 755 ifthen.sh # make script executable$ ifthen.sh rick # test script
• test is used for making comparisons. Can be used in if-then-else statements and looping statements.
• Examples: Compare 2 numbers: test $x –gt $y Compare 2 strings: test $x != $y Check a file’s attributes: test -f $file1
• Shorthand notation uses [] instead of test: [ $x –gt $y ] # note the whitespace!! [ $x != $y ] [ -f $file ]
Relational Testing Using test
Numeric String
-eq Equal to = Equal to
-ne Not equal to != Not equal to
-gt Greater than -n string String is not null
-ge Greater or equal to -z string String is null
-lt Less than string String assigned & not null
-le Less or equal to == Equal to (Bash & Korn)
File -f fName fName exists and is a regular file
-r fName fName exists and is readable
-s fName fName exists and is its size greater than 0
Some of the Relational Operators (see text)
• Good for compound conditions in if-then-else
• Each logical operator has 2 forms.
• Logical OR written as || or -o if [“$0” = “lm”] || [“$0” = “./lm”]; then if [“$0” = “lm”] -o [“$0” = “./lm”]; then
• Logical AND written as && or -a if [“$1” = “list1”] && [“$2” = “list2”]; then if [“$1” = “list1”] -a [“$2” = “list2”]; then
Combining Logical and Relational Operators
# studentinfo.sh
if [ $# -eq 0 ]; then #interactive part
echo -n “Enter student name: ”
read sname
if [ -z “$sname” ]; then
echo “Student name is null” ; exit 2
fi
grep “$sname” “/etc/passwd”
else
grep “$1” “/etc/passwd” #non-interactive part
fi
Example: An Interactive/Non-interactive Script
• The case statement is good for decision making that involves more than two-way branching.
• The general form is:
case expression inpattern1) commands1 ;;
pattern2) commands2 ;;
pattern3) commands3 ;;
. . .
patternn) commandsn ;;
esac• Patterns may have multiple values separated by | e.g., Mon|Tue)
The case Statement
# Use of a case statement to offer a 5 item menu
echo “ Menu\n1. List of files \n2. Processes of user\n3. Today’s date\n4. Users of system\n5. Quit to Unix\nEnter your option #: \c”
read choice
case “$choice” in
1) ls -l;;
2) ps -f;;
3) date;;
4) who ;;
5) exit ;;
*) echo “Invalid option” # ;; not needed for last option
esac
Example: A Menu Script
expr allows for the 4 basic arithmetic operations on numbers: +, -, \*, and / (Note that the multiplication symbol, *, is escaped.)
All arithmetic is integer: the decimal parts are truncated
Some Examples:
$ x=3; y=5
$ expr 3 + 5
$ expr $x - $y
$ expr $x \* $y # escape the asterisk
$ expr $y / $x # decimal is truncated
$ z=`expr $x \* $y`; echo $z
Arithmetic Computation with expr
• When using expr on strings, separate 2 strings with a : (whitespace)
• expr with the regular expression .* calculates the length of a string.
Some Examples:
$ length=expr “rick bournique” : ‘.*’
String Handling with expr and basename
if [ `expr “$name” : ‘.*’` -gt 20 ]; then
• basename with an absolute filename extracts the base filename
basename /etc/passwd # yields passwd
• basename with 2nd argument extracts 2nd string from 1st string.
basename this.is.a.test .a.test # yields this.is
Top Related