Conditional processing within scripts
One of the most useful commands that you will within many of your scripts will be the "if" command. This simple command gives you the ability to control which parts of your script are executed based on certain conditions. The "if" command can be used to test the success of a command, the existence of files or directories. It can also test strings and values using various boolean operators which we will cover a little later.
Using "if" to test the success of a command
One useful function of the "if" command is that you can test whether a command succeeded or failed. In the simple example that follows our if statement checks that our command runs successfully, if the return code was not "0" then the "else" section of our code is executed indicating that our command was not successful. Note all "if" statements must end with a matching "fi" which signifies the end of a particular block of code.
if your_command; then echo "Your command was successful" else echo "Your command was not successful" fi
The following is a simple script to illustrate how this logic works. Firstly we will run a script called "test01.sh" and pass a name (userid). The script will then check to see if the user is known to the system. If the user exists (the command was successful) then the relevant output will be displayed. In the first example, I have used the userid "john" to test this as I know this user already exists on the system. In the second example I have used a userid that does not exist.
#!/bin/bash # if id $1; then echo "Hello $1" else echo "User not found" fi
Output from script test01.sh:
john@john-desktop:~/scripts$ ./test01.sh john uid=1000(john) gid=1000(john) groups=1000(john),4(adm),20(dialout),21(fax),24(cdrom),25(floppy),26(tape),30(dip),44(video),46(plugdev),104(fuse),112(lpadmin),120(admin),122(vboxusers),123(sambashare) Hello john john@john-desktop:~/scripts$ ./test01.sh fred id: fred: No such user User not found
Testing object types and conditions with "if"
Another practical use of the if command is to test objects such as files directories. Using the "if" command we can check for the presence of a particular file. Many other attributes such as size and permissions can also be checked. Below are some examples of the "if" command being used:
if [ -f file_name ];then echo "True - File Exists" else echo "Sorry - File Not Found" fi
In the above example, we are using the "-f" test to check for the presence of a file "file_name". If the file exists, then our condition is true and the message "True - File Exists" is displayed. However, if the condition is false, this means that the file was not found and the message "Sorry - File Not Found" will be displayed.
The script "test02.sh" is an illustration of this logic:
#!/bin/bash # if [ -f /home/john/scripts/myfile.txt ]; then echo "File found" else echo "Sorry, file not found" fi
The output below shows that the file existed the first time the script was run. However,the "rm" command was used to delete the file "myfile.txt". Now when the script was run for a second time it reported the file as not found.:
Output from script test02.sh:
john@john-desktop:~/scripts$ ls -l myfile.txt -rw-rw-r-- 1 john john 518 Oct 22 21:36 myfile.txt john@john-desktop:~/scripts$ ./test02.sh File found john@john-desktop:~/scripts$ rm myfile.txt john@john-desktop:~/scripts$ ./test02.sh Sorry, file not found
Tests on Objects
As we have just seen it is possible to test for the presence of a file, however, there are many more tests that can be used by the "if" statement. To use these we simply use the required "test" and "object" within square brackets:
if [ -test object ];then echo "Test is True" else echo "Test is False" fi
|-b||True if file exists and is a block device|
|-c||True if file exists and is a character device|
|-d||True if file exists and is a Directory|
|-e||True if file exists and is readable|
|-f||True if regular file exists|
|-g||True if file exists and its SGID bit is set|
|-G||True if file exists and is owned by group ID|
|-h||True if symbolic link exists|
|-k||True if file exists and its sticky bit is set|
|-L||True if file exists and is a symbolic link|
|-N||True if file exists and has been modified since last read|
|-O||True if file exists and is owned by user ID|
|-p||True if file exists and is a named pipe|
|-r||True if file exists and is readable|
|-s||True if file exists and is greater then 0 bytes in size|
|-S||True if file exists and is a Socket|
|-t||True if file exists and is readable|
|-r||True if file exists and is readable|
|-u||True if file exists and its SUID bit is set|
|-w||True if file exists and is writeable|
|-x||True if file exists and is executable|
NOT True Tests
All of the above test have been check for a "TRUE" result. However, we can reverse any of the above tests by using the "! exclamation mark. This basically reverses the test.
if [ ! -f /home/john/scripts/myfile.txt ]; then echo "File NOT found" else echo "File Exists" fi
So far we have seen some examples using the basic "if..then..else..fi" statements. However, we can also use the "elif" statement to add further flexibility to our script. The basic structure of the elif statement within an if statement can be seen below:
if [ Conditional Test1 ]; then Statement 1..... elif [ Conditional Test2 ]; then Statement 2..... else Statement 3..... fi
In the above, when "Conditional Test1" is "TRUE" we execute "Statement 1". If "Conditional Test1" is Not True we run our "elif" section.
If "Conditional Test2" is "TRUE" we run "Statement 2" otherwise "Statement 3" is run.
Below is a simple example of how you can use the elif statement within a script:
#!/bin/bash day=$1 if [ $day -lt 10 ] then echo "We are in the first part of the month" elif [ $day -lt 20 ] then echo "We are in the middle of the month" else echo "We are in the last part of the month" fi
Example output from above script:
john@john-desktop:~/scripts$ ./test05.sh 5 We are in the first part of the month john@john-desktop:~/scripts$ ./test05.sh 15 We are in the middle of the month john@john-desktop:~/scripts$ ./test05.sh 25 We are in the last part of the month