Выбрать главу

do

 statements

done

This form should be used if you want to execute statements once for each value in list. For each iteration, the current value of the list is assigned to vcurvar. list can be a variable containing a number of items or a list of values separated by spaces. The second format is as follows:

for curvar

do

 statements

done

In this form, the statements are executed once for each of the positional parameters passed to the shell program. For each iteration, the current value of the positional para meter is assigned to the variable curvar.

This form can also be written as follows:

for curvar in $@

do

 statements

done

Remember that $@ gives you a list of positional parameters passed to the shell program, quoted in a manner consistent with the way the user originally invoked the command.

Suppose that you want to create a backup version of each file in a directory to a subdirectory called backup. You can do the following in bash:

#!/bin/sh

for filename in *

do

 cp $filename backup/$filename

 if [ $? -ne 0 ]; then

  echo "copy for $filename failed"

 fi

done

In the preceding example, a backup copy of each file is created. If the copy fails, a message is generated.

The while Statement

The while statement can be used to execute a series of commands while a specified condition is true. The loop terminates as soon as the specified condition evaluates to False. It is possible that the loop will not execute at all if the specified condition initially evaluates to False. You should be careful with the while command because the loop will never terminate if the specified condition never evaluates to False.

Endless Loops Have Their Place in Shell Programs

Endless loops can sometimes be useful. For example, you can easily construct a simple command that constantly monitors the 802.11b link quality of a network interface by using a few lines of script:

#!/bin/sh

while :

do

 /sbin/iwconfig eth0 | grep Link | tr '\n' '\r'

done

The script outputs the search, and then the tr command formats the output. The result is a simple animation of a constantly updated single line of information:

Link Quality:92/92 Signal leveclass="underline" -11 dBm Noise leveclass="underline" -102 dBm

This technique can also be used to create a graphical monitoring client for X that outputs traffic information and activity about a network interface:

#!/bin/sh

xterm -geometry 75x2 -e \

bash -c \

"while :; do \

 /sbin/ifconfig eth0 | \

 grep 'TX bytes' | tr '\n' '\r' ; \

done"

The simple example uses a bash command-line script (enabled by -c) to execute a command line repeatedly. The command line pipes the output of the ifconfig command through grep, which searches ifconfig's output and then pipes a line containing the string "TX bytes" to the tr command. The tr command then removes the carriage return at the end of the line to display the information inside an /xterm X11 terminal window, automatically sized by the -geometry option:

RX bytes:4117594780 (3926.8 Mb) TX bytes:452230967 (431.2 Mb)

Endless loops can be so useful that Linux includes a command that repeatedly executes a given command line. For example, you can get a quick report about a system's hardware health by using the sensors command. But rather than use a shell script to loop the output endlessly, you can use the watch command to repeat the information and provide simple animation:

$ watch "sensors -f | cut -c 1-20"

In bash, the following format is used for the while flow-control construct:

while expression

do

 statements

done

If you want to add the first five even numbers, you can use the following shell program in bash:

#!/bin/bash loopcount=0 result=0

while [ $loopcount -lt 5 ] do

 loopcount=`expr $loopcount + 1`

 increment=`expr $loopcount \* 2`

 result=`expr $result + $increment`

done

echo "result is $result"

The until Statement

The until statement can be used to execute a series of commands until a specified condition is true. The loop terminates as soon as the specified condition evaluates to True.

In bash, the following format is used:

until expression

do

 statements

done

As you can see, the format of the until statement is similar to that of the while statement, but the logic differs: In a while loop, you execute until an expression iterates to False, but in an until loop, you loop until the expression iterates to True.

If you want to add the first five even numbers, you can use the following shell program in bash:

#!/bin/bash

loopcount=0

result=0

until [ $loopcount -ge 5 ]

do

 loopcount=`expr $loopcount + 1`

 increment=`expr $loopcount \* 2`

 result=`expr $result + $increment`

done

echo "result is $result"

The example here is identical to the example for the while statement, except that the condition being tested is just the opposite of the condition specified in the while statement.

The shift Statement

The shift statement is used to process the positional parameters, one at a time, from left to right. As you'll remember, the positional parameters are identified as $1, $2, $3, and so on. The effect of the shift command is that each positional parameter is moved one position to the left and the current $1 parameter is lost.

The shift statement is useful when you are writing shell programs in which a user can pass various options. Depending on the specified option, the parameters that follow can mean different things or might not be there at all.