Shell Programming

Download Report

Transcript Shell Programming

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 noninteractive (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
read
echo
read
echo
grep
“Enter pattern to be searched: \c” # \c = no newline
var1
“Enter file to be used: \c”
var2
“Searching for $var1 from file $var2”
“$var1” $var2
# quote multiword strings
Non-Interactive Version:
echo
echo
echo
grep
echo
“Program: $0”
# $0 always = script name
“The number of arguments specified is $#”
“The arguments are $*” # all arguments stored in $*
“$1” $2
“\nJob Over”
The Exit Status of a Script
• 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
– exit 0
– exit n
- everything OK, default status is 0
- True, meaning everything ran OK
- 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.
Making Simple Decisions with 2 Logical Operators
&& 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 Decisions with if-then-else Statements
if command is successful
then
Form 1:
excute commands
fi
if command is successful
then
Form 2:
excute commands
else
excute commands
fi
if command is successful
then
excute commands
elif command is successful
Form 3: then
excute commands
else
excute commands
fi
An if-then-else Example
$ pico ifthen.sh
if grep “^$1[: ]” /etc/passwd
# did grep succeed?
then
echo “Pattern found – Job over” # yes, grep worked
else
echo “Pattern not found”
# no, grep failed
fi
$ chmod 755 ifthen.sh
$ ifthen.sh rick
# make script executable
# test script
Relational Testing Using test
• test is used for making comparisons. Can be used in ifthen-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 ]
Some of the Relational Operators (see text)
Numeric
-eq
Equal to
-ne
Not equal to
-gt
Greater than
-ge
Greater or equal to
-lt
Less than
-le
Less or equal to
File
-f fName
-r fName
-s fName
String
=
!=
-n string
-z string
string
==
Equal to
Not equal to
String is not null
String is null
String assigned & not null
Equal to (Bash & Korn)
fName exists and is a regular file
fName exists and is readable
fName exists and is its size greater than 0
Combining Logical and Relational Operators
• 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
Example: An Interactive/Non-interactive Script
# 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
The case Statement
• The case statement is good for decision making that involves more than
two-way branching.
• The general form is:
case expression in
pattern1)
commands1 ;;
pattern2)
commands2 ;;
pattern3)
commands3 ;;
. . .
patternn)
commandsn ;;
esac
• Patterns may have multiple values separated by | e.g., Mon|Tue)
Example: A Menu Script
# 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
Arithmetic Computation with expr
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
$ expr $y / $x
# escape the asterisk
# decimal is truncated
$ z=`expr $x \* $y`; echo $z
String Handling with expr and basename
• 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” : ‘.*’
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