A.3 Other Control Structures


This section describes other important Bourne shell and bash control structures.

A.3.1 The while and until Commands

The while statement is one way to create a loop. It has two forms:

while condition do    commands done until condition do    commands done

In the while form, the commands are executed until the condition becomes false. In the until form, they are executed until the condition becomes true. Here is an example of while:

cat /etc/fstab |  while read DEVICE MOUNT_DIR READONLY FS DUMMY1 DUMMY2  do    fsck (if required) and mount the device  done

This loop takes each line of /etc/fstab in turn (sent to it via cat) and performs an appropriate action for the corresponding device. The while loop will end when read (described later) returns a nonzero status, indicating an end-of-file.

Here is another very similar example, taken from a recent Linux system:

while read des fs type rest; do   case "$fs" in     /) break;;     *)      ;;   esac done < /etc/fstab if [ -e "$des" -a "$type" != "resiserfs" ] then   run fsck fi

Note that the input to the while loop is provided via I/O redirection following the done statement.

A.3.2 The case Command

The case command is a way to perform a branching operation. Here is its syntax:

case str in     pattern_1)      commands       ;;        pattern_2)       commands       ;;     ...    pattern_n)       commands       ;;        *)       commands       ;;  esac

The value in str is compared against each of the patterns. The corresponding commands are executed for the first match that is found. The double semicolons are used to end each section. Wildcards are allowed in the patterns, and a pattern consisting of a single asterisk can serve as a default if no other pattern is matched; it must be placed at the end of the case command.

Here is an example of the case command:

/etc/fsck -p >/dev/console  case $? in                     Select action based on fsck return value.   0)         date >/dev/console          ;;      2)         exit 1      ;;      4)          /sbin/reboot -n          ;;      *)         echo "Unknown error in reboot" > /dev/console         exit 1          ;;  esac

In this example, different commands are run depending on the return value from fsck.

Another typical use of case is found in the files in /etc/init.d on systems with System V-style boot scripts. Here is an abbreviated example:

#! /bin/sh # Start or stop the lp scheduler    case "$1" in    'start')       /usr/lib/lpsched # and other commands       ;;      'stop')       /usr/lib/lpshut > /dev/null 2>&1       ;;      'restart')      $0 stop && $0 start      ;;      *)       echo "usage: $0 {start|stop}"       ;;  esac

This script takes different actions depending on the keyword specified as its argument. The argument it gets at boot time depends on whether it is invoked as an S-file or a K-file (as we noted in Chapter 4).

A.3.3 The for Command

The for command is another way to create loops. Here is its syntax:

for var [ in list ]  do     commands  done

If a list is included, the variable var is set to each value in turn, and the command in the loop are executed. If no list of values is specified, $@ (all script arguments) is used.

Here is an example:

for d in /tmp /usr/tmp /chem/tmp ; do     find $d ! -name tmp -type d -exec rmdir {} \;  done

This loop removes empty subdirectories from under /tmp, /usr/tmp, and /chem/tmp in turn, while not removing those directories themselves (via ! -name tmp of course, it won't remove /tmp/tmp either).

A.3.3.1 The bash arithmetic for loop

bash also offers an arithmetic-style for loop, with the following syntax:

for (( start ; test ; incr )) ; do     commands done

start is an expression evaluated when the loop starts, test is an expression evaluated at the end of each loop iteration, and incr is an expression evaluated whenever the test condition is false. The loop terminates when the test condition is true.

Here is a simple example:

for (( i=1 ; i<10 ; i++ )); do    echo $i done

This loop displays the numbers 0 through 9.

A.3.4 The Null Command

Occasionally, you'll run across a command consisting of just a colon:

:

This null command is typically used when all the work is done in the control statement, and the body of the loop is empty.

Sometimes this command is used as a comment character (since its arguments will be ignored), as in this ancient example:

: attempt to ship remaining files  uucico -r

However, this practice is not recommended, because a line such as the following:

: Hourly cleanup script @(#)cleanup.hourly 2/4/90

(part of which was produced by a source-code control system) produces an error:

./cleanup.hourly: syntax error at line 2: `(' unexpected

This is because syntax checking is still done on the arguments to the null command.



Essential System Administration
Essential System Administration, Third Edition
ISBN: 0596003439
EAN: 2147483647
Year: 2002
Pages: 162

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