Sometimes you might want an operation to repeat until a certain condition becomes true (or until a certain condition is no longer true). This is where looping statements come into play. The Bourne shell supports three different looping constructs for these situations. These are the while loop, the until loop, and the for loop. You will look at each one separately. The while LoopThe while loop takes a test condition as an argument, and repeats the statements inside the loop as long as the condition that is being tested is true. In other words, whatever is enclosed in the loop keeps being executed over and over until it causes a change in the program's variables such that the test condition becomes false. If the condition is already false the first time it is evaluated, the loop will never be executed. For example, the program in Listing 10.7 uses a while loop to count to 20 and display the numbers on the screen. Listing 10.7. Using the while Loop
This program introduces a few new concepts:
Notice that the statements inside the loop are indented. This makes it easy to pick out the statements that are part of the loop when quickly scanning the program's source code. The shell ignores the indentation, so you could have written this program without using it. I recommend you always indent loops, though, using tabs or a specified number of spaces, to make them easier to find when quickly scanning program source code. Tip The space between the bracket ([) and the condition to be tested is mandatory, as is the space immediately before the final bracket (]). Failing to include either one will cause an error. For example, [ $VarA -gt 5 ] will work, but [$VarA -gt 5] will cause an error. The until LoopThe until loop is the opposite of the while loop. It performs the operations inside the loop as long as the condition being tested is not true. When the condition being tested becomes true, the loop exits. If the condition is already true the first time it is evaluated, the loop will never be executed. The while loop and the until loop are very similar. Usually, you can use either one in a program and achieve the same results simply by modifying the condition that is tested for. For example, the counting program that used the while loop can be rewritten to use an until loop by making only two changes in line 4: 4. until [$i -gt 20 ] This program performs the same function performed by the earlier program that uses the while loop. The only difference is that now the loop repeats until the value of i is greater than 20, whereas before it repeated while the value of i was less than or equal to 20. The result is exactly the same, however. Logical AND/OR Statements in while and until LoopsBoth the while loop and the until loop can also work with logical AND/OR statements. A logical AND statement, indicated with the symbol &&, will be carried out if and only if both conditions are true. A logical OR statement (||) will be carried out if either condition is true. The code example in Listing 10.8 shows a logical AND statement, which will execute the while loop only if both statements ("$VarA is equal to 1" and "$VarB is greater than 7") are true; the second statement is not true, so the loop will not execute. Listing 10.8. Using a Logical AND Statement
In this example, the echo statement will not be executed. Because the while loop in this case requires both conditions to be true, the test fails and returns a 0 (false). The code example in Listing 10.9 is identical to the one in Listing 10.8, except you have changed the while test to a logical OR statement. Now, only one of the conditions needs to be true. Therefore, because VarA will always be equal to 1 in this program, the while statement will continuously execute in an endless loop (until you press Ctrl+C). Listing 10.9. Using a Logical OR Statement
The for LoopThe for loop is different from the while and until loops. Instead of evaluating a true/false test condition, the for loop simply performs the statements inside the body of the loop once for each argument it receives in a list. When creating a for loop, you supply it a variable. Each iteration of the for loop changes the value of the variable to the next argument in the list. The for loop continues until the argument list has been exhausted, at which point the loop exits and the program proceeds to the next command. The program in Listing 10.10 uses a for loop along with the bc command you learned about earlier to print the square root of all numbers from 10 through 20: Listing 10.10. Using the for Loop
The output from this program is as follows: 3.16227 3.31662 3.46410 3.60555 3.74165 4.00000 4.12310 4.24264 4.35889 4.47213 Note these important lines in the preceding program:
The shift CommandThe shift command is similar to the for loop. You can use a while loop along with shift to run a loop once for each command-line argument you give when invoking a shell program. As you'll recall from the previous discussion, command-line arguments are stored in numbered variables starting at $1 and going to $9. The shift command shifts the variables one position to the left each time it is run. This means that each time shift is encountered, the information currently stored in $1 "falls off" the end; the information currently stored in $2 is moved to $1, and so on up the list. Listing 10.11 shows an example. Listing 10.11. Using the shift Command
And here's a sample run: # ./shift1 a b c d e The value of $1 is now a. The value of $1 is now b. The value of $1 is now c. The value of $1 is now d. The value of $1 is now e. Here are the notable lines in this program:
One of the most common applications of shift (and for loops) is in shell programs that accept a list of filenames as command-line arguments and then perform a group of operations on each file specified on the command line. The true and false StatementsThe sole purpose of the true and false statements in shell programming is to return a value of true (0) or false (1), respectively. You can use these statements to create infinite loops. As long as there is some condition that can break a program out of an infinite loop, it can be useful to write code that creates one. This is how programs are designed that run continuously and listen for input, such as web servers. The example in Listing 10.12 shows a program that will loop indefinitely. Listing 10.12. Creating an Infinite Loop with true
Obviously, this chapter cannot show you the output of this program because it would go on forever. Line 3 tests for a true condition. And because the argument it tests (TRue) will never return a value of false, the loop will repeat indefinitely. Lines 7, 8, 9, and 10 will never be executed because the program can never get past the loop. (To end this program, press Ctrl+C on your keyboard.) Breaking the LoopSometimes, you might want to break out of a loop before the condition necessary to exit the loop has occurred, and then proceed with the rest of the script. There are two statements that can be used to break a loop without ending the program. The first is the break statement, and the second is the continue statement. The break StatementThe break statement will terminate a loop immediately when it is encountered, regardless of whether the condition required to exit the loop has been met. Listing 10.13 shows a slight modification to the previous "endless loop" program. Listing 10.13. Breaking Out of a Loop
Here's the output of this program: This line will print forever... But... The break statement in the loop causes the loop to terminate immediately and go to the first statement after the loop. In a more complex implementation, you could have a loop that waits for some kind of input to be entered from the user's console or from the network; the loop could test continuously for the existence of a file or the value of a variable, and if that condition becomes true, a break could end the loop. Usually it is considered more elegant to write loops whose exit conditions are constructed to react properly on the right kind of input and to avoid a break when possible. In sufficiently complex programs, however, a break can be just what you need to get out of a jam. The continue StatementThe continue statement causes the loop to immediately jump back to the top and reevaluate the test condition. Any remaining statements in the loop are not executed. Listing 10.14 is another example that uses the "endless loop" program with a slight modification. Listing 10.14. Restarting a Loop Before It Has Ended
This program will indefinitely output "This line will print forever." The rest of the echo statements inside the loop will never be printed because the continue statement preceding them causes the loop to immediately jump back to the top and reevaluate the test condition. |