UNIX Tutorials, Tips, Tricks and Shell Scripts

7 UNIX if-then-else Examples...with Sample Shell Scripts!!! - Part I


While preparing to write this quick shell scripting tutorial on the UNIX if then else statement, I spent a respectable amount of time reviewing some of the more advanced UNIX shell scripts that I have written during the past 15 years not only to see if there was a pattern to my usage of the "if then else" shell scripting construct but also to select a few uncommon usages of the statement which I hope will be both interesting and useful to you.

After each concept is presented I will include a sample shell script which demonstrates usage so that it will be easier for you to understand the concept and, more importantly, incorporate it while writing your own shell scripts.

Here we go...

The UNIX test Command

Before looking at an actual "if then else" statement, it is necessary to understand the UNIX test command since it will be the key component of the if then else statements you use in your shell scripts. The test command is used to evaluate a condition, commonly called an expression, to determine whether is is true or false and then will exit with a status (return code) indicating the same. If the outcome of the expression is true, a zero ("0") is returned. When the expression is false, the exit status will be one ("1").

Although the man page for the test command ("man test") lists the following two syntax options for the command:

test expression

or simply,

[ expression ]

I have personally never used the first format. I am not saying that there may not be appropriate use cases for this particular format, it is just that I have not encountered a task where it was necessary to use it.

IMPORTANT: The test command's man page also includes the comprehensive list of valid expressions you can use with test, which are the same expressions that will be used in your UNIX shell scripts' if than else statements. While writing shell scripts, this the quickest method to find the value you need to use in your expressions.

The examples for the test command will be from the command line prompt since it is overkill to use shell script to demonstrate the concept. Each example will be run from a directory that contains only two files ("fileA" and "template.sh"), and will check to see if a file exists in the current working directory...a task that surely ranks high for first-time shell programmers.

$ ls
fileA template.sh

Example 1a - Using the test Command to determine if a file exists (with "test" keyword)

$ test -f fileA
$ echo $?
0
$ test -f fileB
$ echo $?
1

Example 1b - Using the test Command to determine if a file exists (without "test" keyword)

$ [ -f fileA ]
$ echo $?
0
$ [ -f fileB ]
$ echo $?
1



It should be obvious that both of these examples accomplish the same task, they just use different syntax in doing so. Note that the test command is not limited to single operand expressions, as demonstrated by the next two examples which compare strings and numbers.

Example 1c - Using the test Command to compare two strings

$ [ "UNIX shell scripting" = "UNIX shell programming" ]
$ echo $?
1

TIP: To check for inequality, just add an exclamation point ("!") before the equal sign, which reads is the first string not equal to the second string:

$ [ "UNIX shell scripting" != "UNIX shell programming" ]
$ echo $?
0

Example 1d - Using the test Command to compare two numbers

Are the two numbers equal?

$ [ 10 -eq 20 ]
$ echo $?
1

Is the first number less than the second number?

$ [ 10 -lt 20 ]
$ echo $?
0

Is the first number greater than the second number?

$ [ 10 -gt 20 ]
$ echo $?
1

The key takeaways from the UNIX test command section are:
  1. an exit status of 0 indicates the expression is true
  2. an exit status of 1 indicates the expression is false
  3. there are two formats, but the [ expression ] format is more commonly used than the test expression format
  4. REMEMBER to use the command's man page ("man test") to build your expressions

Now that you have a basic, but good, understanding of the key building block for UNIX if then else statements we can explore the different variations of the if then else scripting construct and consider sample shell scripts to see how they are used.


UNIX if then statement without the else

There are times when it is only necessary to check a single condition and take action based on the outcome without needing to follow an else path in your if then statement.  One scenario that comes to my mind quickly is related to the number of arguments passed to a shell script.  Many programs (shell scripts) will require a minimum number of arguments and should not proceed unless that requirement is met.  Here is a sample shell script that demonstrates how to use a basic if then statement to check the argument count received from the user or program invoking the script:

Example 2 - Checking a shell script's argument count using an if then statement without the else

First, let's look at the contents of the sample script...

$ cat remote_system_administration.sh
#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"

# check argument count
if [ $# -ne 2 ]
then
  echo $USAGE
  exit
fi

and running it without passing any arguments will produce...

$ ./remote_system_administration.sh
USAGE: remote_system_administration.sh <host> <admin_task>

Key takeaways from Example 2's sample script:
  1. it makes use of basename utility, which will remove the directory (path) and suffix from filenames
  2. the USAGE statement is a string defining how the shell script should be invoked
  3. the if statement expression expects exactly 2 arguments, no more and no less
  4. if exactly 2 arguments are not passed to the shell script, it will display the usage string and immediately exit the shell script.  If there were additional lines of code below the if-then statement in this script they would not be executed.
  5. if statements are terminated with fi - "if" spelled backwards

With the basic if then statement (with no else) is out of the way, let's add another if statement that includes the else.




UNIX if then statement with the else

Based on the name of the sample script in the previous section ("remote_system_administration.sh"), the theme or storyline here is that we're writing a shell script that can be used to manage a heterogeneous group of systems in a data center environment that may be running a variant of UNIX (Solaris, AIX, HP-UX, other), a particular Linux distribution (RedHat, CentOS, Ubuntu, other), or another operating system altogether.  I will not include all of the shell script code required to make this a completely functional program since the scope of this tutorial is if then else statement usage and is not intended to show you how to build a fully functional system administration application.  I will, however, insert comments in the script where I envision code for a complete application would go.

For this section, we will introduce an if statement to our script which includes an else in it.

Example 3 - Checking what operating system is running on remote host using an if then statement with the else

The updated script...

$ cat remote_system_administration.sh
#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"

# check argument count
if [ $# -ne 2 ]
then
  echo $USAGE
  exit
fi

# assign arguments to friendly variable names and define additional shell variables as needed
HOST=$1
ADMIN_TASK=$2
USER=livefirelabs

# take action based on host's operating system
HOST_OS=$(/usr/bin/ssh ${USER}@${HOST} uname)

echo "the value of the HOST_OS variable is $HOST_OS"

if [ $HOST_OS = Linux ]
then
  echo "in the Linux path of if statement"
  # here is where linux specific code would go
else
  echo "in the non-Linux path of if statement"
  # here is where non-linux specific code would go
fi

exit 0

Running the script now produces...

$ ./remote_system_administration.sh 192.168.0.1 diskspace
the value of the HOST_OS variable is Linux
in the Linux path of if statement

Key takeaways from Example 3's sample script:
  1. the arguments passed to the script from the command line ("192.168.0.1" and "diskspace") are initially stored in $1 and $2 respectively, and the subsequently are assigned by the shell script to reader-friendly shell variable names...this really helps from a programming and future maintenance perspective!
  2. for details about using ssh to get information from a remote host, see the ssh man page ("man ssh").  You want to configure SSH so that a password is not needed to run the command on the remote system because you do not want to be typing in passwords from an automation perspective.
  3. notice that the value returned from the ssh run of uname on the remote host is stored in the shell variable "HOST_OS"
  4. for the if then else statement, the value stored in the HOST_OS variable is compared to "Linux" and will follow the then path.  If the value stored in HOST_OS was not "Linux" the else path would be followed.
  5. typically, the informational "echo" statements would not be including in a script like this...unless you were debugging a problem with it.  I put these in for your benefit to see that there is actually something happening, and more importantly, correctly happening.  =)
  6. the sample script exits with a return code of 0, indicating to the calling program or command line that it completed successfully

Next, we will add elif to the script so that it will handle another specific (hard-coded) UNIX operating system.


UNIX if then elif else statement

For this example, we will first check to see if the operating system running on the remote host is Solaris ("SunOS") and will secondly perform the "Linux" check by adding and elif then statement to the sample script.

Example 4 - Using elif to add another specific (hard-coded) UNIX operating system

Here is how the new script looks...

#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"

# check argument count
if [ $# -ne 2 ]
then
  echo $USAGE
  exit
fi

# assign arguments to friendly variable names and define additional shell variables as needed
HOST=$1
ADMIN_TASK=$2
USER=livefirelabs

# take action based on host's operating system
HOST_OS=$(/usr/bin/ssh ${USER}@${HOST} uname)

echo "the value of the HOST_OS variable is $HOST_OS"

if [ $HOST_OS = SunOS ]
then
  echo "in the Solaris path of if statement"
  # here is where linux specific code would go
elif [ $HOST_OS = Linux ]
then
  echo "in the Linux path of if statement"
  # here is where linux specific code would go
else
  echo "in the non-Solaris and non-Linux path of if statement"
  # here is where non-linux specific code would go
fi

exit 0

Since the remote system I'm testing the script against is running Linux, this updated script will produce the same output as seen in Example 3. In a real-world environment, you would want to manually test each code path in your shell script to ensure it performs as expected.

$ ./remote_system_administration.sh 192.168.0.1 diskspace
the value of the HOST_OS variable is Linux
in the Linux path of if statement

Key takeaways from Example 4's sample script:
  1. the main different between Example 4 and Example 3 is the introduction of the elif then code so that we could hard-code another specific UNIX operating system, otherwise there is not much to discuss here.
  2. REMEMBER to include a "then" after the elif keyword...just like you do for the "if" keyword.

...and now a little bonus which I hope you will enjoy.

BONUS: How to reduce multi-line if statements in a shell script to a single line of code

Consider the first iteration of our sample shell script, which only checked the argument count passed in to it:

$ cat remote_system_administration.sh
#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"

# check argument count
if [ $# -ne 2 ]
then
  echo $USAGE
  exit
fi

It is possible to reduce the if then statement's 5 lines of code (from "if" to "fi") to a single line of code and still perform the same programmatic task.  This is what the updated sample shell script would look like:

#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"
[ $# -ne 2 ] &&  { echo ${USAGE}; exit ; }

The is how the collapsed statement is read, if the expression is true (the number of arguments is not equal to two) then display the usage string and immediately exit the shell script.  In other words, if the exit status of the test expression is 0 then perform the commands listed on the right side of the ampersands ("&&").  The braces on the right side of the ampersands are only necessary if there are multiple commands to perform.  They are not needed if you only want a single command executed.

One thing I find this short-hand notation useful for when you want debug messages displayed only if a previously defined debug flag is enabled.  I would add the following line of code anywhere in program I wanted a debug message displayed, or the value of a variable displayed. etc.

$ cat debug.sh
#!/bin/ksh

DEBUG=1

[ $DEBUG -eq 1 ] && echo "starting sorting routine"

$ ./debug.sh
starting sorting routine
$

To turn off debug messages, or other action taken when debug is enabled, just set the shell variable DEBUG to 0.  This variable would be defined at the top of your shell script.  You could also use something similar, just change the variable name and command to run on the right of the ampersands, to enable logging certain output to a logfile.

If you wanted only to perform the command(s) on the right side of the ampersand if the test expression is false (exist status of 1), you would use two pipes ("||") instead:

#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"
[ $# -ne 2 ] || echo "Thank you for supplying two arguments"

Run results with 2 arguments:

$ ./remote_system_administration.sh 192.168.0.1 diskspace
Thank you for supplying two arguments
$

Run results with only 1 argument:

$ ./remote_system_administration.sh 192.168.0.1
$

And YES, it is even possible to create a fully functioning if then else (emphasis on the "else") statement with a single line of code:

$ cat ./remote_system_administration.sh
#!/bin/ksh

USAGE="USAGE: $(basename $0) <host> <admin_task>"
[ $# -ne 2 ] && { echo ${USAGE}; exit ; } || echo "Thank you for supplying two arguments"
$

$ ./remote_system_administration.sh 192.168.0.1
USAGE: remote_system_administration.sh <host> <admin_task>
$

$ ./remote_system_administration.sh 192.168.0.1 diskspace
Thank you for supplying two arguments
$

Here is one last if statement for your consideration...

if [ $YOU_LIKED_THIS_ARTICLE = Yes ]
then
  echo "Please share this page with others using the social media buttons below."
  echo "Thank you!!!"
fi

;-)  Seriously, I hope you enjoyed this tutorial on UNIX if then else statements and find it both useful and beneficial in all of your shell scripting endeavors.

Do you need a better understanding of UNIX shell script if then else statements or other shell scripting concepts and constructs? Either of these online courses is a good place to start...

UNIX and Linux Operating System Fundamentals contains a very good "Introduction to UNIX Shell Scripting" module, and should be taken if you are new to the UNIX and Linux operating system environments or need a refresher on key concepts.

UNIX Shell Scripting is a good option if you are already comfortable with UNIX or Linux and just need to sharpen your knowledge about shell scripting and the UNIX shell in general.

Both courses include access to a real server in our Internet Lab for completing the course's hands-on exercises, which are used to re-enforce the key concepts presented in the course. Any questions you may have while taking the course are answered by an experienced UNIX technologist.

Thanks for reading, and happy shell scripting!