On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

# 10.3. Loop Control

Commands Affecting Loop Behavior

break, continue

The break and continue loop control commands [1] correspond exactly to their counterparts in other programming languages. The break command terminates the loop (breaks out of it), while continue causes a jump to the next iteration (repetition) of the loop, skipping all the remaining commands in that particular loop cycle.

Example 10-20. Effects of break and continue in a loop

 ```#!/bin/bash LIMIT=19 # Upper limit echo echo "Printing Numbers 1 through 20 (but not 3 and 11)." a=0 while [ \$a -le "\$LIMIT" ] do a=\$((\$a+1)) if [ "\$a" -eq 3 ] || [ "\$a" -eq 11 ] # Excludes 3 and 11. then continue # Skip rest of this particular loop iteration. fi echo -n "\$a " # This will not execute for 3 and 11. done # Exercise: # Why does loop print up to 20? echo; echo echo Printing Numbers 1 through 20, but something happens after 2. ################################################################## # Same loop, but substituting 'break' for 'continue'. a=0 while [ "\$a" -le "\$LIMIT" ] do a=\$((\$a+1)) if [ "\$a" -gt 2 ] then break # Skip entire rest of loop. fi echo -n "\$a " done echo; echo; echo exit 0```

The break command may optionally take a parameter. A plain break terminates only the innermost loop in which it is embedded, but a break N breaks out of N levels of loop.

Example 10-21. Breaking out of multiple loop levels

 ```#!/bin/bash # break-levels.sh: Breaking out of loops. # "break N" breaks out of N level loops. for outerloop in 1 2 3 4 5 do echo -n "Group \$outerloop: " # -------------------------------------------------------- for innerloop in 1 2 3 4 5 do echo -n "\$innerloop " if [ "\$innerloop" -eq 3 ] then break # Try break 2 to see what happens. # ("Breaks" out of both inner and outer loops.) fi done # -------------------------------------------------------- echo done echo exit 0```

The continue command, similar to break, optionally takes a parameter. A plain continue cuts short the current iteration within its loop and begins the next. A continue N terminates all remaining iterations at its loop level and continues with the next iteration at the loop, N levels above.

Example 10-22. Continuing at a higher loop level

 ```#!/bin/bash # The "continue N" command, continuing at the Nth level loop. for outer in I II III IV V # outer loop do echo; echo -n "Group \$outer: " # -------------------------------------------------------------------- for inner in 1 2 3 4 5 6 7 8 9 10 # inner loop do if [ "\$inner" -eq 7 ] then continue 2 # Continue at loop on 2nd level, that is "outer loop". # Replace above line with a simple "continue" # to see normal loop behavior. fi echo -n "\$inner " # 7 8 9 10 will never echo. done # -------------------------------------------------------------------- done echo; echo # Exercise: # Come up with a meaningful use for "continue N" in a script. exit 0```

Example 10-23. Using "continue N" in an actual task

 ```# Albert Reiner gives an example of how to use "continue N": # --------------------------------------------------------- # Suppose I have a large number of jobs that need to be run, with #+ any data that is to be treated in files of a given name pattern in a #+ directory. There are several machines that access this directory, and #+ I want to distribute the work over these different boxen. Then I #+ usually nohup something like the following on every box: while true do for n in .iso.* do [ "\$n" = ".iso.opts" ] && continue beta=\${n#.iso.} [ -r .Iso.\$beta ] && continue [ -r .lock.\$beta ] && sleep 10 && continue lockfile -r0 .lock.\$beta || continue echo -n "\$beta: " `date` run-isotherm \$beta date ls -alF .Iso.\$beta [ -r .Iso.\$beta ] && rm -f .lock.\$beta continue 2 done break done # The details, in particular the sleep N, are particular to my #+ application, but the general pattern is: while true do for job in {pattern} do {job already done or running} && continue {mark job as running, do job, mark job as done} continue 2 done break # Or something like `sleep 600' to avoid termination. done # This way the script will stop only when there are no more jobs to do #+ (including jobs that were added during runtime). Through the use #+ of appropriate lockfiles it can be run on several machines #+ concurrently without duplication of calculations [which run a couple #+ of hours in my case, so I really want to avoid this]. Also, as search #+ always starts again from the beginning, one can encode priorities in #+ the file names. Of course, one could also do this without `continue 2', #+ but then one would have to actually check whether or not some job #+ was done (so that we should immediately look for the next job) or not #+ (in which case we terminate or sleep for a long time before checking #+ for a new job).```

 The continue N construct is difficult to understand and tricky to use in any meaningful context. It is probably best avoided.

### Notes

 [1] These are shell builtins, whereas other loop commands, such as while and case, are keywords.

 Published under the terms of the GNU General Public License Design by Interspire