What is Bash?

Bash is a UNIX shell and a scripting language. It allows you to write scripts with UNIX commands which will be run sequentially. You can also use the typical programming semantics like for loops to run a command multiple times or control flow statements like if else.

Shebang

Every bash script should have what’s called a Shebang at the top of the file, wich is the sign #! followed by the absolute path of the bash installation. Usually it is as follows:

#!/bin/bash

Variables

Bash allows the use of variables. We can store a value in a variable like so:

foo="var"

Notice there’s no space on both sides of the equal sign. Bash requires no spaces around the equal sign when assigning a value to a variable.

We can print a variable using the echo command:

foo="var"
echo $foo

If you want to print a string with that variable you can use double quotes:

foo="var"
echo "I'm printing a $foo"

By using back ticks you can assign the output of a command to a variable:

dirContents=`ls`
echo $dirContents

Arithmetic operations with variables

There are two ways of doing arithmetic operations with variables

By using the keyword let

a=10
let b=a*2
let c=a+b
let d=11%2
echo $a $b $c $d
output: 10 20 30 1

By using double parenthesis

a=10
((b=a*2))
((c=a+b))
((d=11%2))
echo $a $b $c $d
output: 10 20 30 1

If we don’t use these methods and do something like this:

a=10
b=a*2
c=$a+$b
echo $a $b $c
output: 10 a*2 10+a*2

You can see that it doesn’t evaluate the arithmetic operations since they get treated as a string.

We can also use a Linux program called bc (basic calculator) by standard input redirection:

z=5
z=`bc <<< $z+5`
echo $z
output: 5

Control flow

If statements

They can be written in three different ways: with [], with [[]] or with test

num=10
if [ $((num % 2)) -eq 0 ]
then
    echo "It's an even number"
else
    echo "It's an odd number"
fi

count=100
if [[ $count -gt 100 ]]
then
  echo "Count is more than 100"
else
  echo "Count is not more than 100"
fi

if test 3 == 3; then echo "yes"; fi

output: It's an even number
        Count is not more than 100
        yes

You probably noticed the -eq or -gt on the if statements. Those are the comparison operators used on the string ifs and that’s what they mean:

  • -eq=
  • -ne!=
  • -lt<
  • -gt>
  • -le<=
  • -ge>=

Numeric if statements

There is actually a forth way of writing if statements by using the double parenthesis we used earlier. They allow us to perform numerical comparisons more easily.

num=10
if (( $num % 2 == 0 ))
then
    echo "It's an even number"
else
    echo "It's an odd number"
fi
output: It's an even number

Case

Case is similar to the switch statements of most programming languages. They work the following way

case expression in
    pattern1 )
        statements ;;
    pattern2 )
        statements ;;
    ...
esac

Here’s an example:

num=2
case "$num" in
1)  echo "It's number 1"
    ;;
2)  echo  "It's number 2"
    ;;
3)  echo  "It's number 3"
    ;;
*) echo "It's some other number"
   ;;
esac
output: "It's number 2"

Loops

Like most programming languages bash has loops for running commands repeatedly.

While loops

The while keeps running while the specified condition is true. We can write them as follows:

count=0
while [ $count -lt 5 ]; do
    echo -ne "$count "
    ((count++))
done
output: 0 1 2 3 4

Notice we use the same comparison operators we used on the if statements. The ‘-ne’ on the echo command means that it will not break to a new line after printing the variable on screen.

Until loop

It works the same way as the while loop except that the loop keeps running until the specified condition is true.

count=0
until [ $count -gt 5 ]; do
    echo -ne "$count "
    ((count++))
done
output: 0 1 2 3 4 5

For loops

For loop are a bit different from while and until. There are different types of for loops in bash. The first type goes like this:

values='1 2 3 4'
for value in $values; do
    echo -ne "$value "
done
output: 1 2 3 4 

As you can see, the for loop goes through all the values in the specified variable.

Another type of for loop is the following:

for value in {1..4}; do
    echo -ne "$value "
done
output: 1 2 3 4

Which is similar to the previous one, but since we know we want to iterate numbers from 1 to 4 we can just write {1..4}, which generates a list of numbers from 1 to 4, instead of writing them manually on a variable.

If we wanted to print all odd numbers from 1 to 10 we could write something like this:

for value in {1..10..2}; do
    echo -ne "$value "
done
output: 1 3 5 7 9 

What {1..10..2} does is generate a list from 1 to 10 but incrementing the previous number by two. So it would write 1, then we add 1+2 so it writes 3, next would be 3+2 which is 5…

We can also write for loops like in other programming languages:

for ((i = 0 ; i < 5 ; i++)); do
  echo -ne "$i "
done
output: 0 1 2 3 4

What this loop does is, declare a variable i with value 0, and after every iteration increments i by 1. The loop keeps running until the condition (second position inside the parenthesis, in this case i < 5) is no longer met.