Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [77]

By Root 830 0
commands, or commands involving && and ||.

The only difference between while and until is how the exit status of condition is treated. while continues to loop as long as condition exited successfully. until loops as long as condition exits unsuccessfully. For example:

pattern=... pattern controls shortening of string

while [ -n "$string" ] While string is not empty

do

process current value of $string

string=${string%$pattern} Lop off part of string

done

In practice, the until loop is used much less than the while loop, but it can be useful when you need to wait for an event to happen. This is shown in Example 6-2.

Example 6-2. Wait for a user to log in, using until

# wait for specified user to log in, check every 30 seconds

printf "Enter username: "

read user

until who | grep "$user" > /dev/null

do

sleep 30

done

It is possible to pipe into a while loop, for iterating over each line of input, as shown here:

generate data |

while read name rank serial_no

do

...

done

In such cases, the command used for the while loop's condition is usually the read command. We present a real-life example later in Section 7.3.1, when discussing here-documents. In Section 7.6, we show that you can also pipe the output of a loop into another command.

break and continue

Not everything in the shell came straight from Algol 68. The shell borrowed the break and continue commands from C. They are used to leave a loop, or to skip the rest of the loop body, respectively. The until...do wait-for-a-user script in Example 6-2 can be rewritten more conventionally, as shown here in Example 6-3.

Example 6-3. Wait for a user to log in, using while and break

# wait for specified user to log in, check every 30 seconds

printf "Enter username: "

read user

while true

do

if who | grep "$user" > /dev/null

then

break

fi

sleep 30

done

The true command does nothing but exit successfully. It's used for writing infinite loops—loops that run forever. When you write an infinite loop, you have to place an exit condition in the body of the loop, just as was done here. There is an analogous, but considerably less-used command, false, which does nothing, but it does so unsuccessfully. It would be used in an infinite until false ... loop.

The continue command is used to start the next iteration of a loop early, before reaching the bottom of a loop's body.

Both the break and the continue commands take an optional numeric argument. This indicates how many enclosing loops should be broken out of or continued. (Use $((...)) if the loop count needs to be an expression calculated at runtime.) For example:

while condition1 Outer loop

do ...

while condition2 Inner loop

do ...

break 2 Break out of outer loop

done

done

... Execution continues here after break

It is interesting to note that break and continue, particularly with the ability to break or continue multiple loop levels, compensate in a clean fashion for the absence of a goto keyword in the shell language.

shift and Option Processing

We briefly mentioned the shift command earlier, in Section 6.1.2.2. shift is used when working with command-line arguments. Its job is to move them left by one (or more). After executing shift, the original $1 is lost; it is replaced with the old value of $2. The new value of $2 is the old value of $3, and so on. The value of $# decreases each time, as well. shift accepts an optional argument, which is the number of places to shift by: the default is 1.

Simple option processing is often done by combining while, case, break, and shift, like so:

# set flag vars to empty

file= verbose= quiet= long=

while [ $# -gt 0 ] Loop until no args left

do

case $1 in Check first arg

-f) file=$2

shift Shift off "-f" so that shift at end gets value in $2

;;

-v) verbose=true

quiet=

;;

-q) quiet=true

verbose=

;;

-l) long=true

;;

--) shift By convention, - - ends options

break

;;

-*) echo $0: $1: unrecognized option >&2

;;

*) break Nonoption argument, break while loop

;;

esac

shift Set up for next iteration

Return Main Page Previous Page Next Page

®Online Book Reader