Scripting with Bash#

Most Linux distributions come with the Bash shell. It is a very simple shell, but it is also a very powerful one. It is an updated version of the Bourne shell, which is the most common shell on UNIX systems. As a result, it is the most commonly used shell on UNIX systems and knowning how to script in the Bash shell is a prerequisite to use Linux as a power user on any system.

Using Variables#

Variables in shells are strings that are assigned to a name. The name is followed by an equals sign, and then the value of the variable. The value can be a string, a number, or a special value. The example below assign variable name i to value 0, and can be referred to by calling $i.

Assigning a value to a variable#
1#!/bin/bash
2
3i=0
4echo $i

Command substitution#

Assinging a variable to a value can also be done by command substitution where the output of a command is assigned to a variable. In the example below instead of directly assigning variable to the value, the command date +%s is executed as indicated by the backticks ` surrounding the command and the result is stored as a value and the variable is assigned to it.

Command substitution#
1#!/bin/bash
2
3i=`date +%s`
4echo $i

Exit-codes#

Every command returns an exit-code after it ran and the value is stored in the environment variable $?. By executing command echo $? the stored exit-code value can be viewed, but it will also directly updated as the command to view it will generate a new exit-code.

Note

An exit code, or sometimes known as a return code, is the code returned to a parent process by an executable. On POSIX systems the standard exit code is 0 for success and any number from 1 to 255 for anything else.

The example below shows the exit-code after the command cat file.txt was able to read the file.

Exit-code after a successful command#
1$ cat file.txt
2Hello World
3$ echo $?
40

If the command cat filedoesnotexist.txt is executed and was unable to read the file and gives an exit-code of 1.

Exit-code after a failed command#
1$ cat filedoesnotexist.txt
2cat: filedoesnotexist.txt: No such file or directory
3$ echo $?
41
5$ echo $?
60

Warning

Exit-codes are updated after executing any command and may cause scripts to fail when people try to debug scripts by adding statements to display exit-codes.

Conditional structures#

If-then-else#

Conditional structures are used to evaluate a condition and execute a command if the condition is true. Based on this a command is executed if the condition is true or another if the condition is false. Starting with the if-then-else as shown in the example below, show the condition on line 4 where a comparision is made between variable i having value 1 and the value 1. As both have the same value the condition is true

Example of if-then-else#
1#!/bin/bash
2
3i=1
4if [ $i -eq 1 ]
5then
6    echo "i equals 1"
7else
8    echo "i does not equal 1"
9fi

The if-then-else construct can also be extended to include an else-if statement. On line 8 in the example below the keyword elif allows for a new conditional comparision.

If-then-else with and second if-then-else#
 1#!/bin/bash
 2
 3i=1
 4j=2
 5if [ $i -eq 1 ]
 6then
 7    echo "i equals 1"
 8elif [ $j -eq 2 ]
 9then
10    echo "j equals 2"
11else
12    echo "i and j do not equal 1 or 2"
13fi

The if-then-else construct can also be simplified to do only something when the condition is true. The example below will not display anything as the statement in not true as 1 isn’t equal to 2.

If-then#
1#!/bin/bash
2
3i=1
4if [ $i -eq 2 ]
5then
6    echo "i equals 1"
7fi

Short-circuit evaluation#

The shell also allows to write short form conditional statements. This is can be used by using /usr/bin/[ or [ as the first character of the condition. It is an alternative to the test command and with the && and || operators the action can be defined.

If-then-else#
1#!/bin/bash
2
3i=1
4[ $i -eq 1 ] && echo "i equals 1"

Case statement#

Beside the if-then-else construct, the shell also allows to define a case statement. This is used to evaluate a value and execute a command based on the value. This makes the script more flexible and can be used to evaluate multiple values.

Case statement#
 1#!/bin/bash
 2
 3i=1
 4
 5case $i in
 6    1) echo "One";;
 7    2) echo "Two";;
 8    3) echo "Three";;
 9    *) echo "Unknown";;
10esac

Loops#

For loops#

Iterating over a list of values is done by using a for loop. The for loop is used to iterate over a list of values. The for loop is defined by the keyword for, followed by the name of the variable, followed by the keyword in, followed by the list of values. The list of values is separated by a space.

For loop#
1#!/bin/bash
2
3for i in {1..10}
4do
5    echo $i
6done

While loops#

Counter based loops are used to iterate over a list of values. The while loop is defined by the keyword while, followed by the condition, followed by the keyword do, followed by the commands, followed by the keyword done. In the example below the while loop keep echo’ing the text Hello  World! as long as the value of variable i is lower or equals to the value 10. The value for variable i must be manually increased as in show on line 8 while with For loops this is managed.

While loop#
1#!/bin/bash
2
3i=1
4while [ $i -le 10 ]
5do
6    echo "Hello World!"
7    sleep 1
8    i=(( $i + 1 ))
9done

Note

A while loop can also be used to have an endless loop. The colon : show on line 3 indicates that the condition is always true and will keep looping until a break is give.

An infinate while loop#
1#!/bin/bash
2
3while :; do
4    echo "Hello World!"
5    sleep 1
6done