{"id":239,"date":"2016-02-11T23:29:54","date_gmt":"2016-02-11T23:29:54","guid":{"rendered":"http:\/\/blog.paranoidprofessor.com\/?p=239"},"modified":"2016-07-06T14:02:33","modified_gmt":"2016-07-06T14:02:33","slug":"command-line-fun-flow-control","status":"publish","type":"post","link":"https:\/\/blog.paranoidprofessor.com\/index.php\/2016\/02\/11\/command-line-fun-flow-control\/","title":{"rendered":"command line fun &#8211; flow control"},"content":{"rendered":"<p>Shell scripting is like any other programming language as far as control statements go.\u00a0 To be honest, all your favorite control statements can be whipped up using either if\/then statement or a loop.<\/p>\n<p>The good news is that we don&#8217;t need to create this from scratch but can instead use all the same control statements as most modern languages.<\/p>\n<p><strong>IF \/ THEN \/ ELSE<\/strong><\/p>\n<p>The general statement is the same as other languages but the actual comparison verbs are slightly different.<\/p>\n<table>\n<tbody>\n<tr>\n<th>Operator<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td>-z<\/td>\n<td>string is null<\/td>\n<\/tr>\n<tr>\n<td>! -z<\/td>\n<td>string is not null<\/td>\n<\/tr>\n<tr>\n<td>==<\/td>\n<td>test for strings being equal<\/td>\n<\/tr>\n<tr>\n<td>!=<\/td>\n<td>test for strings not equal<\/td>\n<\/tr>\n<tr>\n<td>-eq<\/td>\n<td>numeric equals<\/td>\n<\/tr>\n<tr>\n<td>-ne<\/td>\n<td>numeric not equals<\/td>\n<\/tr>\n<tr>\n<td>-gt<\/td>\n<td>numeric greater than<\/td>\n<\/tr>\n<tr>\n<td>-ge<\/td>\n<td>numeric greater than equals<\/td>\n<\/tr>\n<tr>\n<td>-lt<\/td>\n<td>numeric less than<\/td>\n<\/tr>\n<tr>\n<td>-le<\/td>\n<td>numeric less than equals<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The comparison verbs are different depending on whether comparing numbers or strings.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nA=1\r\nB=4\r\n\r\nif [ $A -eq $B ]\r\nthen\r\n  echo $A\r\n\u00a0 echo A equals B\r\nelse\r\n  echo $A $B\r\n\u00a0 echo A not equal B\r\nfi\r\n<\/code><\/pre>\n<\/div>\n<p><strong>WHILE<\/strong><\/p>\n<p>The while construct simply does a comparison at the beginning and executes the body if the statement is true.\u00a0 The comparison verbs are the same list of verbs as seen above for the if\/then\/else statement.<\/p>\n<p>Just like in C, you can use either break to exit the loop completely, the continue statement causes the program control to pass to the conditional tests.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nA=1\r\nB=4\r\n\r\nwhile [ $A -le $B ]\r\ndo\r\n\u00a0 echo hi $A\r\n\u00a0 A=$(($A + 1))\r\ndone\r\n<\/code><\/pre>\n<\/div>\n<p><strong>FOR LOOP<\/strong><\/p>\n<p>The for loop, when it can be used, is perhaps one of the best control structures to use.\u00a0 It could be a personal hangup of mine, but the advantage is that the initialization, test and increment is all conveniently located in one spot.\u00a0 This makes it hard to forget to setup one of these three crucial components.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nfor (( idx=1 ; $idx &lt; 9 ; idx=`expr $idx + 1` )) ; \r\ndo \r\n   echo \"some neat message here $idx\" \r\ndone<\/code><\/pre>\n<\/div>\n<p>Oddly enough, I almost never use the for loop in this manner.\u00a0 The much more convenient way of using it is almost like some sort of set operator or iterator.\u00a0 Rather than counting something, the for loop is used to iterate through a small collection of items.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nVALS=\"1 2 3 5 8 13 21\"\r\nfor i in $VALS\r\ndo\r\n   echo $i\r\ndone<\/code><\/pre>\n<\/div>\n<p>This particular example is pretty unimaginative and unrealistic.\u00a0 The better case is to collect some data from a file or file-system and then to process each one.\u00a0 This could be to run a special program against each file individually, or to perform some special steps one at a time.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nCSVFILE=output.csv\r\nFILES=`ls -1 control-data-2016*`\r\nfor i in $FILES\r\ndo\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 CNT=`wc -l it.sh | sed -e 's\/ .*\/\/'`\r\n\u00a0\u00a0 echo $i,$CNT &gt;&gt; $CSVFILE\r\n\u00a0\u00a0 gzip -9 $i\r\ndone\r\n<\/code><\/pre>\n<\/div>\n<p>This small script is probably not the simplest way to count the number of lines in a file and prepare the output for a comma delimited file but it shows one iterative method of processing files.<\/p>\n<p><strong>SWITCH STATEMENT<\/strong><\/p>\n<p>The switch statement is much nicer than a really big if\/then\/else block.\u00a0 Simply separate each case block with two semicolons.<\/p>\n<div class=\"sbody-code\">\n<pre><code>#!\/bin\/bash\r\nargument=$1\r\n\r\ncase \"$argument\" in\r\n\r\n\u00a0 start) \r\n\u00a0 echo starting service \r\n\u00a0 ;;\r\n\r\n\u00a0 stop) \r\n\u00a0 echo stopping service \r\n\u00a0 ;;\r\n\r\n\u00a0 *) \r\n\u00a0 echo unknown command $argument encountered \r\n\u00a0 ;;\r\n\r\nesac\r\n<\/code><\/pre>\n<\/div>\n<p>Depending on the problem, I am sure there are a number of uses for this structure but I don&#8217;t normally have much use for it.<\/p>\n<p>The main reason is due to quite a few other operators that can be used with the if\/then\/else or while structures.\u00a0 It makes it easy to verify that files or directories exist and are readable or writable.<\/p>\n<table>\n<tbody>\n<tr>\n<th>Operator<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td>-f<\/td>\n<td>file exists<\/td>\n<\/tr>\n<tr>\n<td>-d<\/td>\n<td>directory exists<\/td>\n<\/tr>\n<tr>\n<td>-w<\/td>\n<td>if file is writable<\/td>\n<\/tr>\n<tr>\n<td>-r<\/td>\n<td>if file is readable<\/td>\n<\/tr>\n<tr>\n<td>-x<\/td>\n<td>if file is executable<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Shell scripting is like any other programming language as far as control statements go.\u00a0 To be honest, all your favorite control statements can be whipped up using either if\/then statement or a loop. The good news is that we don&#8217;t &hellip; <a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2016\/02\/11\/command-line-fun-flow-control\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,20],"tags":[17,39],"_links":{"self":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/239"}],"collection":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":11,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":719,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions\/719"}],"wp:attachment":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}