Intro to bash scripting
Nov 18, 2020 · 948 words · 5 minute read
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.