Shell Scripts

Why shell script?

  • Automation

  • Monitoring and troubleshooting

  • Raise alarm and send notifications

  • etc.

Types of shell script

There are 2 types of CLI or shelss that are used in Unix-based OS like Linux and macOS

  • Bash (Bourne-Again-SHell)

  • Shell

To check which shell program is currently running on your OS

echo $SHELL

# use sh command to go to Bourne shell
phuong@home:~$ sh
$ 

Scripting 101

Var

  • Case-sensitive, lower-case and underscores.

  • Start with $. e.g $my_variable

  • no space trailing allow

# bad example
my_var = hello-world

# good example
my_var=hello-world
  • Include variable in a string in bash, using curly braces

# include var in string
mkdir ${folder_name}_bk

Passing args

# argument start from 1, so the 1st arg is $1
# assigning var to 1st arg
folder_name=$1
mkdir $foler_name

Input prompting

# read the input from command line
read folder_name
mkdir $folder_name

# prompting user before reading
read -p "Enter folder name:" folder_name
mkdir $folder_name

Operations (expr)

# must have while space before and after = sign
$ expr 6 + 3
9

$ expr 6 - 3
3

# using \ to escape the multiply sign
$ expr 6 \* 3
18

# only return decimal, not supporting floating point
$ expr 10 / 3
3

# to return floating point, using bc -l
$ expr 10 / 3 | bc -l
3.333333

Double parentheses

Using double parenteses to perform arithmetic operations and comparation

Arithmetic operations

# no need to escape * using \ any more
# no need to use expr
a=5
b=10
c=$((a + b))
d=$((a * b))

Comparison

a=5
b=10
if ((a < b)); then
    echo "a is less than b"
fi

Flow control

Condition

a=5
b=10
# using double [[ ]] to check the condition
if [[a -lt b]]
then
    echo "a is less than b"
elif [[a -gt b]]
    echo "a is greater than b"
else
    echo "a equal b"
fi

Loop

For loop

for x in 1 2 3
do
    echo "do this $x time"
done

# or to loop 1 to 3
for x in {1..3}
do
    echo "do this $x time"
done

# using double brackets
for (( x = 1 ; x <= 3; x++ ))
do
     echo "do this $x time"
done

# loop through files in folder
for file in $(ls)
do
    echo "Line count of $file is $(cat $file | wc -l)"
done

While loop

# basic usage
while True
do
    echo "Hello world"
    break
done

Case

# as switch statement
month_number=$1
case $month_number in
    1) echo "January" ;;
    2) echo "February" ;;
    3) echo "March" ;;
    4) echo "April" ;;
    5) echo "May" ;;
    6) echo "June" ;;
    7) echo "July" ;;
    8) echo "August" ;;
    9) echo "September" ;;
    10) echo "October" ;;
    11) echo "November" ;;
    *) echo "December" ;;
esac

Shebang

Shebang/Hashbang

Add the shebang line to the top of the script, so that even if the script is running from an unsupported shells, it will use the /bin/bash interpreter.

#!/bin/bash

Exit code

# exit code stored in $
# 0: success
$ ls -la
$ echo $?
0

# >0: failure
$ lss
$ echo $?
127

# you can specify an exit code by using exit command
exit 25

Function

Using function to break up large script to smaller one. 1 function only performs a task.

#!/bin/bash

function add() {
  sum=$(( $1 + $2 ))
  # this statement like return statement
  echo $sum
}

result=$(add 3 5)
echo "The result is $result"

Best practices

  • Design for re-usable, avoid duplicate code

  • Should not require to be edited before running

  • Use command line arguments to pass inputs.

  • Always return approriate exit codes in your script (0: success, >0: failure)

  • The shebang is placed at the 1st line of the script.

Resources

Last updated