command line fun – flow control

Shell scripting is like any other programming language as far as control statements go.  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’t need to create this from scratch but can instead use all the same control statements as most modern languages.


The general statement is the same as other languages but the actual comparison verbs are slightly different.

Operator Description
-z string is null
! -z string is not null
== test for strings being equal
!= test for strings not equal
-eq numeric equals
-ne numeric not equals
-gt numeric greater than
-ge numeric greater than equals
-lt numeric less than
-le numeric less than equals

The comparison verbs are different depending on whether comparing numbers or strings.


if [ $A -eq $B ]
  echo $A
  echo A equals B
  echo $A $B
  echo A not equal B


The while construct simply does a comparison at the beginning and executes the body if the statement is true.  The comparison verbs are the same list of verbs as seen above for the if/then/else statement.

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.


while [ $A -le $B ]
  echo hi $A
  A=$(($A + 1))


The for loop, when it can be used, is perhaps one of the best control structures to use.  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.  This makes it hard to forget to setup one of these three crucial components.

for (( idx=1 ; $idx < 9 ; idx=`expr $idx + 1` )) ; 
   echo "some neat message here $idx" 

Oddly enough, I almost never use the for loop in this manner.  The much more convenient way of using it is almost like some sort of set operator or iterator.  Rather than counting something, the for loop is used to iterate through a small collection of items.

VALS="1 2 3 5 8 13 21"
for i in $VALS
   echo $i

This particular example is pretty unimaginative and unrealistic.  The better case is to collect some data from a file or file-system and then to process each one.  This could be to run a special program against each file individually, or to perform some special steps one at a time.

FILES=`ls -1 control-data-2016*`
for i in $FILES
   CNT=`wc -l | sed -e 's/ .*//'`
   echo $i,$CNT >> $CSVFILE
   gzip -9 $i

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.


The switch statement is much nicer than a really big if/then/else block.  Simply separate each case block with two semicolons.


case "$argument" in

  echo starting service 

  echo stopping service 

  echo unknown command $argument encountered 


Depending on the problem, I am sure there are a number of uses for this structure but I don’t normally have much use for it.

The main reason is due to quite a few other operators that can be used with the if/then/else or while structures.  It makes it easy to verify that files or directories exist and are readable or writable.

Operator Description
-f file exists
-d directory exists
-w if file is writable
-r if file is readable
-x if file is executable


This entry was posted in Command line, programming and tagged , . Bookmark the permalink.