> For the complete documentation index, see [llms.txt](https://mamawhocode.gitbook.io/devops/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mamawhocode.gitbook.io/devops/fundamentals/shell-scripts.md).

# Shell Scripts

## Why shell script?

* Automation
* Monitoring and troubleshooting
* Raise alarm and send notifications
* etc.

<figure><img src="/files/BT1Iqy5LqkBEOl8oUuzA" alt=""><figcaption></figcaption></figure>

### 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

```sh
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

```sh
# bad example
my_var = hello-world

# good example
my_var=hello-world
```

* Include variable in a string in bash, using curly braces

```sh
# include var in string
mkdir ${folder_name}_bk
```

### Passing args

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

### Input prompting

```sh
# 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)

```sh
# 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

#### &#x20;Arithmetic operations

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

#### Comparison

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

## Flow control

### Condition

```sh
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

```sh
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

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

### Case

```sh
# 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.

```sh
#!/bin/bash
```

### Exit code

<figure><img src="/files/9ZR9qn4pi6it67s8wMtV" alt=""><figcaption></figcaption></figure>

```sh
# 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.

```sh
#!/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

{% embed url="<https://quickref.me/bash>" %}
Bash cheat sheet
{% endembed %}

{% embed url="<https://kodekloud.com/courses/shell-scripts-for-beginners/>" %}
Very basic course to learn Shell scripting
{% endembed %}
