{"id":1674,"date":"2013-07-12T12:40:37","date_gmt":"2013-07-12T12:40:37","guid":{"rendered":"http:\/\/blog.designed79.co.uk\/?p=1674"},"modified":"2013-07-12T12:44:56","modified_gmt":"2013-07-12T12:44:56","slug":"break-and-continue-in-bash","status":"publish","type":"post","link":"https:\/\/blog.designed79.co.uk\/?p=1674","title":{"rendered":"Break and Continue in Bash"},"content":{"rendered":"<p>Commands affecting loop behavior<\/p>\n<p>break, continue<br \/>\nThe 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 of the loop, skipping all the remaining commands in that particular loop cycle.<\/p>\n<p>Example Effects of break and continue in a loop<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">#!\/bin\/bash<br \/>\n<br \/>\nLIMIT=19 &nbsp;# Upper limit<br \/>\n<br \/>\necho<br \/>\necho &quot;Printing Numbers 1 through 20 (but not 3 and 11).&quot;<br \/>\n<br \/>\na=0<br \/>\n<br \/>\nwhile [ $a -le &quot;$LIMIT&quot; ]<br \/>\ndo<br \/>\n&nbsp;a=$(($a+1))<br \/>\n<br \/>\n&nbsp;if [ &quot;$a&quot; -eq 3 ] || [ &quot;$a&quot; -eq 11 ] &nbsp;# Excludes 3 and 11.<br \/>\n&nbsp;then<br \/>\n&nbsp; &nbsp;continue &nbsp; &nbsp; &nbsp;# Skip rest of this particular loop iteration.<br \/>\n&nbsp;fi<br \/>\n<br \/>\n&nbsp;echo -n &quot;$a &quot; &nbsp; # This will not execute for 3 and 11.<br \/>\ndone <br \/>\n<br \/>\n# Exercise:<br \/>\n# Why does the loop print up to 20?<br \/>\n<br \/>\necho; echo<br \/>\n<br \/>\necho Printing Numbers 1 through 20, but something happens after 2.<br \/>\n<br \/>\n##################################################################<br \/>\n<br \/>\n# Same loop, but substituting 'break' for 'continue'.<br \/>\n<br \/>\na=0<br \/>\n<br \/>\nwhile [ &quot;$a&quot; -le &quot;$LIMIT&quot; ]<br \/>\ndo<br \/>\n&nbsp;a=$(($a+1))<br \/>\n<br \/>\n&nbsp;if [ &quot;$a&quot; -gt 2 ]<br \/>\n&nbsp;then<br \/>\n&nbsp; &nbsp;break &nbsp;# Skip entire rest of loop.<br \/>\n&nbsp;fi<br \/>\n<br \/>\n&nbsp;echo -n &quot;$a &quot;<br \/>\ndone<br \/>\n<br \/>\necho; echo; echo<br \/>\n<br \/>\nexit 0<\/div><\/div>\n<p>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.<\/p>\n<p>Example Breaking out of multiple loop levels<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">#!\/bin\/bash<br \/>\n# break-levels.sh: Breaking out of loops.<br \/>\n<br \/>\n# &quot;break N&quot; breaks out of N level loops.<br \/>\n<br \/>\nfor outerloop in 1 2 3 4 5<br \/>\ndo<br \/>\n&nbsp; echo -n &quot;Group $outerloop: &nbsp; &quot;<br \/>\n<br \/>\n&nbsp; # --------------------------------------------------------<br \/>\n&nbsp; for innerloop in 1 2 3 4 5<br \/>\n&nbsp; do<br \/>\n&nbsp; &nbsp; echo -n &quot;$innerloop &quot;<br \/>\n<br \/>\n&nbsp; &nbsp; if [ &quot;$innerloop&quot; -eq 3 ]<br \/>\n&nbsp; &nbsp; then<br \/>\n&nbsp; &nbsp; &nbsp; break &nbsp;# Try &nbsp; break 2 &nbsp; to see what happens.<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# (&quot;Breaks&quot; out of both inner and outer loops.)<br \/>\n&nbsp; &nbsp; fi<br \/>\n&nbsp; done<br \/>\n&nbsp; # --------------------------------------------------------<br \/>\n<br \/>\n&nbsp; echo<br \/>\ndone &nbsp;<br \/>\n<br \/>\necho<br \/>\n<br \/>\nexit 0<\/div><\/div>\n<p>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.<\/p>\n<p>Example Continuing at a higher loop level<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">#!\/bin\/bash<br \/>\n# The &quot;continue N&quot; command, continuing at the Nth level loop.<br \/>\n<br \/>\nfor outer in I II III IV V &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # outer loop<br \/>\ndo<br \/>\n&nbsp; echo; echo -n &quot;Group $outer: &quot;<br \/>\n<br \/>\n&nbsp; # --------------------------------------------------------------------<br \/>\n&nbsp; for inner in 1 2 3 4 5 6 7 8 9 10 &nbsp;# inner loop<br \/>\n&nbsp; do<br \/>\n<br \/>\n&nbsp; &nbsp; if [[ &quot;$inner&quot; -eq 7 &amp;&amp; &quot;$outer&quot; = &quot;III&quot; ]]<br \/>\n&nbsp; &nbsp; then<br \/>\n&nbsp; &nbsp; &nbsp; continue 2 &nbsp;# Continue at loop on 2nd level, that is &quot;outer loop&quot;.<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Replace above line with a simple &quot;continue&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # to see normal loop behavior.<br \/>\n&nbsp; &nbsp; fi &nbsp;<br \/>\n<br \/>\n&nbsp; &nbsp; echo -n &quot;$inner &quot; &nbsp;# 7 8 9 10 will not echo on &quot;Group III.&quot;<br \/>\n&nbsp; done &nbsp;<br \/>\n&nbsp; # --------------------------------------------------------------------<br \/>\n<br \/>\ndone<br \/>\n<br \/>\necho; echo<br \/>\n<br \/>\n# Exercise:<br \/>\n# Come up with a meaningful use for &quot;continue N&quot; in a script.<br \/>\n<br \/>\nexit 0<\/div><\/div>\n<p>Example Using continue N in an actual task<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\"># Albert Reiner gives an example of how to use &quot;continue N&quot;:<br \/>\n# ---------------------------------------------------------<br \/>\n<br \/>\n# &nbsp;Suppose I have a large number of jobs that need to be run, with<br \/>\n#+ any data that is to be treated in files of a given name pattern<br \/>\n#+ in a directory. There are several machines that access<br \/>\n#+ this directory, and I want to distribute the work over these<br \/>\n#+ different boxen.<br \/>\n# &nbsp;Then I usually nohup something like the following on every box:<br \/>\n<br \/>\nwhile true<br \/>\ndo<br \/>\n&nbsp; for n in .iso.*<br \/>\n&nbsp; do<br \/>\n&nbsp; &nbsp; [ &quot;$n&quot; = &quot;.iso.opts&quot; ] &amp;&amp; continue<br \/>\n&nbsp; &nbsp; beta=${n#.iso.}<br \/>\n&nbsp; &nbsp; [ -r .Iso.$beta ] &amp;&amp; continue<br \/>\n&nbsp; &nbsp; [ -r .lock.$beta ] &amp;&amp; sleep 10 &amp;&amp; continue<br \/>\n&nbsp; &nbsp; lockfile -r0 .lock.$beta || continue<br \/>\n&nbsp; &nbsp; echo -n &quot;$beta: &quot; `date`<br \/>\n&nbsp; &nbsp; run-isotherm $beta<br \/>\n&nbsp; &nbsp; date<br \/>\n&nbsp; &nbsp; ls -alF .Iso.$beta<br \/>\n&nbsp; &nbsp; [ -r .Iso.$beta ] &amp;&amp; rm -f .lock.$beta<br \/>\n&nbsp; &nbsp; continue 2<br \/>\n&nbsp; done<br \/>\n&nbsp; break<br \/>\ndone<br \/>\n<br \/>\nexit 0<br \/>\n<br \/>\n# &nbsp;The details, in particular the sleep N, are particular to my<br \/>\n#+ application, but the general pattern is:<br \/>\n<br \/>\nwhile true<br \/>\ndo<br \/>\n&nbsp; for job in {pattern}<br \/>\n&nbsp; do<br \/>\n&nbsp; &nbsp; {job already done or running} &amp;&amp; continue<br \/>\n&nbsp; &nbsp; {mark job as running, do job, mark job as done}<br \/>\n&nbsp; &nbsp; continue 2<br \/>\n&nbsp; done<br \/>\n&nbsp; break &nbsp; &nbsp; &nbsp; &nbsp;# Or something like `sleep 600' to avoid termination.<br \/>\ndone<br \/>\n<br \/>\n# &nbsp;This way the script will stop only when there are no more jobs to do<br \/>\n#+ (including jobs that were added during runtime). Through the use<br \/>\n#+ of appropriate lockfiles it can be run on several machines<br \/>\n#+ concurrently without duplication of calculations [which run a couple<br \/>\n#+ of hours in my case, so I really want to avoid this]. Also, as search<br \/>\n#+ always starts again from the beginning, one can encode priorities in<br \/>\n#+ the file names. Of course, one could also do this without `continue 2',<br \/>\n#+ but then one would have to actually check whether or not some job<br \/>\n#+ was done (so that we should immediately look for the next job) or not<br \/>\n#+ (in which case we terminate or sleep for a long time before checking<br \/>\n#+ for a new job).<\/div><\/div>\n<p>The continue N construct is difficult to understand and tricky to use in any meaningful context. It is probably best avoided.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Commands affecting loop behavior break, continue The break and continue loop control commands [1] correspond exactly to their counterparts in other programming [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1674","post","type-post","status-publish","format-standard","hentry","category-info-on-tech"],"_links":{"self":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1674"}],"version-history":[{"count":0,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1674\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}