|
|
< Day Day Up > |
|
8.5. Conditional Constructs and Flow ControlConditional commands allow you to perform some task(s) based on whether a condition succeeds or fails. The if command is the simplest form of decision making; the if/else command allows a two-way decision; and the if/elif/else command allows a multiway decision. The Bourne shell expects a command to follow an if. The command can be a system command or a built-in command. The exit status of the command is used to evaluate the condition. To evaluate an expression, the built-in test command is used. This command is also linked to the bracket symbol. Either the test command is used, or the expression can be enclosed in set of single brackets. Shell metacharacters (wildcards) are not expanded by the test command. The result of a command is tested, with zero status indicating success and nonzero status indicating failure. See Table 8.4.
8.5.1 Testing Exit Status: The test CommandThe following examples illustrate how the exit status is tested. The test command is used to evaluate conditional expressions, returning true or false. It will return a zero exit status for true and a nonzero exit status for false. The test command or brackets can be used. (Refer back to Table 8.4.) Example 8.11.(At the Command Line) 1 $ name=Tom 2 $ grep "$name" /etc/passwd Tom:8ZKX2F:5102:40:Tom Savage:/home/tom:/bin/ksh 3 $ echo $? 0 Success! 4 $ test $name != Tom 5 $ echo $? 1 Failure 6 $ [ $name = Tom ] # Brackets replace the test command 7 $ echo $? 0 Success 8 $ [ $name = [Tt]?m ] # Wildcards are not evaluated by the test command 9 $ echo $? 1 Failure EXPLANATION
8.5.2 The if CommandThe simplest form of conditional is the if command. The command or UNIX utility following the if construct is executed and its exit status is returned. The exit status is usually determined by the programmer who wrote the utility. Typically, if the exit status is zero, the command succeeded and the statement(s) after the then keyword are executed. In the C shell, the expression following the if command is a Boolean-type expression as in C. But in the Bourne and Korn shells, the statement following the if is a command or group of commands. If the exit status of the command being evaluated is zero, the block of statements after the then is executed until fi is reached. The fi terminates the if block. If the exit status is nonzero, meaning that the command failed in some way, the statement(s) after the then keyword are ignored and control goes to the line directly after the fi statement. It is important that you know the exit status of the commands being tested. For example, the exit status of grep is reliable in letting you know whether grep found the pattern it was searching for in a file. If grep is successful in its search, it returns a 0 exit status; if not, it returns 1. The sed and awk programs also search for patterns, but they will report a successful exit status regardless of whether they find the pattern. The criteria for success with sed and awk is correct syntax, not functionality.[2]
FORMAT
if command
then
command
command
fi
---------------------------------
if test expression
then
command
fi
or
if [ expression ]
then
command
fi
-------------------------------
Example 8.12.1 if ypmatch "$name" passwd > /dev/null 2>&1 2 then echo Found $name! 3 fi EXPLANATION
Example 8.13.
1 echo "Are you okay (y/n) ?"
read answer
2 if [ "$answer" = Y -o "$answer" = y ]
then
echo "Glad to hear it."
3 fi
EXPLANATION
8.5.3 The exit Command and the ? VariableThe exit command is used to terminate the script and return to the command line. You may want the script to exit if some condition occurs. The argument given to the exit command is a number ranging from 0 to 255. If the program exits with 0 as an argument, the program exited with success. A nonzero argument indicates some kind of failure. The argument given to the exit command is stored in the shell's ? variable. Example 8.14.
(The Script)
# Name: bigfiles
# Purpose: Use the find command to find any files in the root
# partition that have not been modified within the past n (any
# number within 30 days) days and are larger than 20 blocks
# (512-byte blocks)
1 if [ $# -ne 2 ]
then
echo "Usage: $0 mdays size " 1>&2
exit 1
2 fi
3 if [ $1 -lt 0 -o $1 -gt 30 ]
then
echo "mdays is out of range"
exit 2
4 fi
5 if [ $2 -le 20 ]
then
echo "size is out of range"
exit 3
6 fi
7 find / -xdev -mtime $1 -size +$2 -print
(The Command Line)
$ bigfiles
Usage: bigfiles mdays size
$ echo $?
1
$ bigfiles 400 80
mdays is out of range
$ echo $?
2
$ bigfiles 25 2
size is out of range
$ echo $?
3
$ bigfiles 2 25
(Output of find prints here)
EXPLANATION
8.5.4 Checking for Null ValuesWhen checking for null values in a variable, use double quotes to hold the null value or the test command will fail. Example 8.15.(The Script) 1 if [ "$name" = "" ] # Alternative to [ ! "$name" ] or [ -z "$name" ] then echo The name variable is null fi (From System showmount program, which displays all remotely mounted systems) remotes=`/usr/sbin/showmount` 2 if [ "X${remotes}" != "X" ] then /usr/sbin/wall ${remotes} ... 3 fi EXPLANATION
8.5.5 The if/else CommandThe if/else command allows a two-way decision-making process. If the command after the if fails, the commands after the else are executed. FORMAT
if command
then
command(s)
else
command(s)
fi
Example 8.16.
(The Script)
#!/bin/sh
1 if ypmatch "$name" passwd > /dev/null 2>&1[a]
2 then
echo Found $name!
3 else
4 echo "Can't find $name."
exit 1
5 fi
EXPLANATION
Example 8.17.(The Script) #!/bin/sh # Scriptname: idcheck # purpose: check user ID to see if user is root. # Only root has a uid of 0. # Format for id output:uid=9496(ellie) gid=40 groups=40 # root's uid=0 1 id=`id | nawk –F'[=(]' '{print $2}'` # Get user ID echo your user id is: $id 2 if [ $id –eq 0 ] then 3 echo "you are superuser." 4 else echo "you are not superuser." 5 fi (The Command Line) 6 $ idcheck your user id is: 9496 you are not superuser. 7 $ su Password: 8 # idcheck your user id is: 0 you are superuser EXPLANATION
8.5.6 The if/elif/else CommandThe if/elif/else command allows a multiway decision-making process. If the command following the if fails, the command following the elif is tested. If that command succeeds, the commands under its then statement are executed. If the command after the elif fails, the next elif command is checked. If none of the commands succeeds, the else commands are executed. The else block is called the default. FORMAT
if command
then
command(s)
elif command
then
commands(s)
elif command
then
command(s)
else
command(s)
fi
Example 8.18.(The Script) #!/bin/sh # Scriptname: tellme 1 echo -n "How old are you? " read age 2 if [ $age -lt 0 -o $age -gt 120 ] then echo "Welcome to our planet! " exit 1 fi 3 if [ $age -ge 0 -a $age -lt 13 ] then echo "A child is a garden of verses" elif [ $age -ge 13 -a $age -lt 20 ] then echo "Rebel without a cause" elif [ $age -ge 20 -a $age -lt 30 ] then echo "You got the world by the tail!!" elif [ $age -ge 30 -a $age -lt 40 ] then echo "Thirty something..." 4 else echo "Sorry I asked" 5 fi (The Output) $ tellme How old are you? 200 Welcome to our planet! $ tellme How old are you? 13 Rebel without a cause $ tellme How old are you? 55 Sorry I asked EXPLANATION
8.5.7 File TestingOften when writing scripts, your script will require that there are certain files available and that those files have specific permissions, are of a certain type, or have other attributes. (See Table 8.4 on page 333.) You will find file testing a necessary part of writing dependable scripts. When if statements are nested, the fi statement always goes with the nearest if statement. Indenting the nested ifs makes it easier to see which if statement goes with which fi statement. Example 8.19.
(The Script)
#!/bin/sh
file=./testing
EXPLANATION
8.5.8 The null CommandThe null command, represented by a colon, is a built-in, do-nothing command that returns an exit status of 0. It is used as a placeholder after an if command when you have nothing to say, but need a command or the program will produce an error message because it requires something after the then statement. Often the null command is used as an argument to a looping command to make the loop a forever loop. Example 8.20.(The Script) 1 name=Tom 2 if grep "$name" databasefile > /dev/null 2>&1 then 3 : 4 else echo "$1 not found in databasefile" exit 1 fi EXPLANATION
Example 8.21.(The Command Line) 1 $ DATAFILE= 2 $ : ${DATAFILE:=$HOME/db/datafile} $ echo $DATAFILE /home/jody/ellie/db/datafile 3 $ : ${DATAFILE:=$HOME/junk} $ echo $DATAFILE /home/jody/ellie/db/datafile EXPLANATION
Example 8.22.
(The Script)
#!/bin/sh
1 # Name:wholenum
# Purpose:The expr command tests that the user enters an integer
echo "Enter a number."
read number
2 if expr "$number" + 0 > /dev/null 2>&1
then
3 :
else
4 echo "You did not enter an integer value." 1782
exit 1
5 fi
EXPLANATION
8.5.9 The case CommandThe case command is a multiway branching command used as an alternative to the if/elif command. The value of the case variable is matched against value1, value2, and so forth, until a match is found. When a value matches the case variable, the commands following the value are executed until the double semicolons are reached. Then execution starts after the word esac (case spelled backwards). If the case variable is not matched, the program executes the commands after the *), the default value, until ;; or esac is reached. The *) value functions the same as the else statement in if/else conditionals. The case values allow the use of shell wildcards and the vertical bar (pipe symbol) for ORing two values. FORMAT
case variable in
value1)
command(s)
;;
value2)
command(s)
;;
*)
command(s)
;;
esac
Example 8.23.
(The Script)
#!/bin/sh
# Scriptname: colors
1 echo -n "Which color do you like?"
read color
2 case "$color" in
3 [Bb]l??)
4 echo I feel $color
echo The sky is $color
5 ;;
6 [Gg]ree*)
echo $color is for trees
echo $color is for seasick;;
7 red | orange) # The vertical bar means "OR"
echo $color is very warm!;;
8 *)
echo No such color as $color;;
9 esac
10 echo "Out of case"
EXPLANATION
8.5.10 Creating Menus with the here document and case CommandThe here document and case command are often used together. The here document is used to create a menu of choices that will be displayed to the screen. The user will be asked to select one of the menu items, and the case command will test against the set of choices to execute the appropriate command. Example 8.24.(The .profile file) echo "Select a terminal type: " 1 cat << ENDIT 1) vt 120 2) wyse50 3) sun 2 ENDIT 3 read choice 4 case "$choice" in 5 1) TERM=vt120 export TERM ;; 2) TERM=wyse50 export TERM ;; 6 3) TERM=sun export TERM ;; 7 esac 8 echo "TERM is $TERM." (The Output) $ . .profile Select a terminal type: 1) vt120 2) wyse50 3) sun 3 <-- User input TERM is sun. EXPLANATION
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
< Day Day Up > |
|