Home / code / shell

Conditional and looping statements

if...then...else...fi

The if...then...else construct is the easiest conditional that you can use. This is where, however, the code samples are going to start to grow a little bit. For example, let's say you've got a variable called name and you want to see if it holds the value John. If it, does you'll print "Hi John", if not "Get lost".

if test "$name" = "John"
then
  echo "Hi John"
else
  echo "Get Lost"
fi
You can use multiple if...then...else statements inside one another. A shortcut for writing else if is elseif, the rest of the syntax remain the same.

elif

the elif construction is easy if you need nested if's

if test "$name" = "John"
then
  echo "Hi John"
elif test "$name" = "Chris"
then
  echo "Hello Chris"
else
  echo "Get Lost"
fi

&&

A shortcut conditional statement is && this can very quickly shorten your code if you only want to write a quick and dirty if...then statement. If you'd like to test to see whether name is John and the print howdy! if it is, you can shorten everything to the following:

test "$name" = "John" && echo "Howdy!"
If the first expression evaluates true, the the code immediately following the && is executed.

||

Similar to the previous statement, the || will execute the second statement if the first statement fails. For example, let's modify the code we just looked at so that it will print You aren't John! if the variable name isn't John!:

test "$name" = "John" || echo "You aren't John!"

case...in...esac

If you've got a bunch of possible conditions, one way to get around tons of if...then..else statements is to use the case statement. The case statement lets you compare a variable to a variety of possible matches and then execute specific commands i a match is made. A default case is also available that will match anything, if none of the specific matches are made.
Example, if you want to personalize messages for the 3 users who might use your program, you could use something like this:

case $name in
John) echo "Hi John, how's everything?"
;;
Rob) echo "Hey Rob."
;;
Sara) echo "How are you doing, Sara ?"
;;
*) echo "I have no idea who you are!"
esac

while...do...done

The while statement lets a portion of your program execute repeatedly while a certain condition is true. Let's say that you want to keep prompting a user for his name as long as he keeps typing the name Barney.

name="Barney"
while test "$name" = "Barney"
do
  echo -n "Enter your name: "
  read name
done
You might notice that the program starts by assigning the value Barney to name. This is necessary so that the first time the while statement executes, the expression is true.

until...do...done

The until statement is very similar to while except that it executes until an expression becomes true. A useful example for an until statement would be a loop when you want to accept user input until they type a certain word. Let's look at the last example again, except this time we'll only accept input until the word "Barney" is typed.

until test "$name"="Barney"
do
  echo -n "Enter your name: "
  read name
done

for...in...do...done AND "*"

The shell scripting implementation of the for loop is a bit different from what you might expecting if you've used for...next loops before. The for command cycles through a list of "words" (filenames,usernames, and the like - not necessarily actual words) and allow you to operate on each word in the list.

Before looking at how this is used, it's a good idea to understand what the * character does. This character tells the shell to expand the * into a list of matching filenames. For example, typing * is shorthand for "a list of files in the current directory." Typing *html would expand the list to all files ending with "html" in the current directory. This is a very easy and useful way to generate a list.

For a example of these 2 constructs, how about a loop that cycles through all the html files in the current directory, storing each one (temporarily) in the variable filename while using the wc command to print the numbers of lines in the files:

for filename in *html
do
  echo -n "Filename: $filename contains "
  wc -l $filename
done
You can also use the special $* variable to cycle through all of the parameters that the user specified on the command line.

Since bash v3.0 you can also but ranges:

for i in {1..10}
do
  echo $i
done

And since bash v4.0 you can even use step values:

for i in {0..10..2}
do
     echo "Welcome $i times"
done
Goes from 0 to 10 in steps of 2.

 

TOP

Latest script:

 

Books: