Section 6.10. Control Structures


[Page 226 (continued)]

6.10. Control Structures

To take advantage of the comparisons described above, you can use various commands that control what command is executed next. While these structures can be used in the interactive Bash shell, they are most often used when writing Bash shell scripts.

6.10.1. case .. in .. esac

The case statement lets you specify multiple actions to be taken when the value of a variable matches one or more values (Figure 6-30).

Figure 6-30. Description of the case shell command.


Shell command: case
case word in
  pattern { | pattern }* ) commands ;;
  ...
esac

Execute the commands specified by commands when the value of word matches the pattern specified by pattern. The ")" indicates the end of the list of patterns to match. The ";;" is required to indicate the end of the commands to be executed.


For example, a section of Bash shell script to print out the home location of the NFL teams listed in our earlier example might look like this:

case ${teamname[$index]} in   "Dallas Cowboys") echo "Dallas, TX" ;;   "Denver Broncos") echo "Denver, CO" ;;   "New York Giants"|"New York Jets") echo "New York, NY";;   . . .   *) echo "Unknown location" ;; esac 


Note the special use of the pattern "*" as the last pattern. If you go through all the patterns and have never matched anything, this is useful to catch this situation. It is permissible to not match any patterns, in which case, none of the commands will be executed.

Here's an example script called "menu.sh" that makes use of a case control structure (this script is also available online; see the Preface for information):

#!/bin/bash echo menu test program 
[Page 227]
stop=0 # reset loop termination flag. while test $stop -eq 0 # loop until done. do cat << ENDOFMENU # display menu. 1 : print the date. 2, 3: print the current working directory. 4 : exit ENDOFMENU echo echo -n 'your choice? ' # prompt. read reply # read response. echo case $reply in # process response. "1") date # display date. ;; "2"|"3") pwd # display working directory. ;; "4") stop=1 # set loop termination flag. ;; *) # default. echo illegal choice # error. ;; esac echo done


Here's the output from the "menu.sh" script:

$ bash menu.sh menu test program   1   : print the date.   2, 3: print the current working directory.   4   : exit your choice?  1 Thu May  5 07:09:13 CST 2005   1   : print the date.   2, 3: print the current working directory.   4   : exit your choice?  2 
[Page 228]
/home/glass 1 : print the date. 2, 3: print the current working directory. 4 : exit your choice? 5 illegal choice 1 : print the date. 2, 3: print the current working directory. 4 : exit your choice? 4 $ _


6.10.2. if .. then .. elif .. then .. else .. fi

The if statement lets you compare two or more values and branch to a block of commands depending on how the values relate (Figure 6-31).

Figure 6-31. Description of the if shell command.


Shell command: if
if test1then
  commands1;
[elif test2then
  commands2;]
[else commands3;]
fi

test1 is a conditional expression (discussed above), which, if true, causes the commands specified by commands1 to be executed. If test1 tests false, then if an "elif" structure is present, the next test, test2, is evaluated ("else if"). If test2 evaluates to true, then the commands in commands2 are executed. The "else" construct is used when you always want to run commands after a test evaluated as false.


As an example, let's assume we have a special case for a couple of our NFL teams when printing information about them. We might determine which file of information to print like this:

# $index has been set to some arbitrary team in the list # if [ "${teamname[$index]}" == "Minnesota Vikings" ]; then 
[Page 229]
cat "vikings.txt" # print "special" info elif [ "${teamname[$index]}" == "Chicago Bears" ]; then cat "bears.txt" # ditto else cat "nfl.txt" # for everyone else, print the standard fi


6.10.3. for .. do .. done

The for construct is best used when you have a known set of items you wish to iterate over (e.g., a list of hostnames, filenames, or something of that sort) (Figure 6-32). You might use a comparison to jump out of such a loop, or you might simply wish to process each item in the list sequentially.

Figure 6-32. Description of the for shell command.


Shell command: for
for name in word { word }*
do
  commands
done

Perform commands for each word in list with $name containing the value of the current word.


One example of this use might be if you needed to sort the contents of all text files in a directory:

$ ls abc.txt    def.txt    ghi.txt $ for file in *.txt do   sort $file > $file.sorted done $ ls abc.txt           def.txt           ghi.txt abc.txt.sorted    def.txt.sorted    ghi.txt.sorted $ _ 


6.10.4. while/until .. do .. done

The while and until constructs work in a similar fashion, performing a loop while or until a test condition is met ("while" in the case that the condition is initially true and you want to loop until it becomes false, "until" in the case that the condition is initially false and you want to loop until it becomes true), as described in Figure 6-33.


[Page 230]

Figure 6-33. Description of the while and until shell commands.


Shell commands: while/until
while test
do
  commands
done


until test
do
  commands
done

In a while statement, perform commands as long as the expression test evaluates to true. In an until statement, perform commands as long as the expression test evaluates to false (i.e., until test is true).


These constructs are useful when you don't know exactly when the status of the test condition will be changed. Here's an example of a script that uses an until control structure:

$ cat until.sh      ...list the script. x=1 until [ $x -gt 3 ] do  echo x = $x  (( x = $x + 1 )) done $ bash until.sh      ...execute the script. x = 1 x = 2 x = 3 $ _ 


Here's an example of a script that uses a while control structure to generate a small multiplication table:

$ cat multi.sh         ...list the script. if [ $# -lt 1 ]; then    echo "Usage: multi number"    exit fi x=1                       # set outer loop value while [ $x -le $1 ]       # outer loop do 
[Page 231]
y=1 # set inner loop value while [ $y -le $1 ] do # generate one table entry (( entry = $x * $y )) echo -e -n "$entry\t" (( y = $y + 1 )) # update inner loop count done echo # blank line (( x = $x + 1 )) # update outer loop count done $ bash multi.sh 7 ...execute the script. 1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49


6.10.5. trap

The trap command allows you to specify a command that should be executed when the shell receives a signal of a particular value. Figure 6-34 gives the syntax.

Figure 6-34. Description of the trap shell command.

Shell command: trap [ [ command ] { signal } +]

The trap command instructs the shell to execute command whenever any of the numbered signals signal are received. If several signals are received, they are trapped in numeric order. If a signal value of 0 is specified, then command is executed when the shell terminates. If command is omitted, then the traps of the numbered signals are reset to their original values. If command is an empty string, then the numbered signals are ignored. If trap is executed with no arguments, a list of all the signals and their trap settings is displayed. For more information on signals and their default actions, see Chapter 12, "Systems Programming."


Here's an example of a script that uses the trap control structure. When a Control-C was typed, the shell executed the echo command followed by the exit command:

$ cat trap.sh                    ...list the script. trap 'echo Control-C; exit 1' 2  # trap Ctl-C (signal #2) while test 1 do  echo infinite loop  sleep 2                         # sleep for two seconds. 
[Page 232]
done $ bash trap.sh ...execute the script. infinite loop infinite loop ^C ...I typed a Control-C here. Control-C ...displayed by the echo command. $ _





Linux for Programmers and Users
Linux for Programmers and Users
ISBN: 0131857487
EAN: 2147483647
Year: 2007
Pages: 339

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net