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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mamawhocode.gitbook.io/devops/fundamentals/shell-scripts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
