# Shell Script - Basic [Part - 2]

**<mark>Bash Scripting Cheat Sheet:</mark>**  
`https://cheatography.com/danilobanjac/cheat-sheets/bash-scripting-language-cheat-sheet/`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682768453322/a05dcc7b-ce87-42a4-b214-49a1c5c54fa7.png align="center")

1. if elif
    
2. loops
    
3. functions
    
    ### **<mark>if elif</mark>**
    
    `#!/bin/bash`
    
    `#Defining Variables`
    
    `a=100`  
    `b=200`  
    `c=300`
    
    `#using if condition`
    
    `#Note: When you are using && and gt (AND , Greater then condtion, in that you need to use [[ ]] double quare bracket )`
    
    `if [[ $a -gt $b && $a -gt $c ]]`  
    `then`  
    `echo "A is biggest"`  
    `elif [[ $b - gt $a && $b -gt $c ]]`  
    `then`  
    `echo "B is biggest"`  
    `else`  
    `echo "C isbiggest"`  
    `fi`
    
    **<mark>Note:</mark>** `The comparison statement should be within the square bracket [] and there should be at least one space between the bracket and your statement and the values on either side.`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913421450/0e110ec9-0073-4e35-95a1-d205989f3e96.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913457629/fd3fbb5b-ee07-47bc-b753-e13238b3bd71.png align="center")
    
    <mark>=</mark> `(Equal to operator) should only be used to compare strings for numerical operations you can use -eg, -ne, gt, etc...`
    
    ### <mark>For Loops</mark>
    
    `for ((i=0; i<10; i++)) do echo "$i" ; done`  
    `max=10 ; for (( i=2; i <= $max; ++i )) do echo "$i" ; done`
    
    `for i in {10..20}; do echo "$i"; done`  
    `for i in 1 2 3 4 5; do echo "$i" ; done`
    
    `#!/bin/bash`  
    `` for j in `seq 1 10` ``  
    `do echo $j`  
    `done`
    
    * Create multiple files using touch  
        `touch file-{2..10}.txt`
        
    * To list/iterate all the files within the Directory  
        `for FILE in * do echo $FILE done`
        
    * To list/iterate only the file with end with .txt within the Directory
        
        `for FILE in *.txt do echo $FILE done`
        
    * Taking Input from a text file  
        `for i in $(cat input.txt) do echo $i done`  
        Or  
        ``for i in `cat input.txt` do echo $i done``
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682923978644/4cc40a14-0fbe-43bd-9889-e209cabc8a36.png align="center")
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682922179865/b16961be-4a3b-47d7-8c2d-a75e6b653fea.png align="center")
        
        ### <mark>While Loops</mark>
        
        * The syntax of a while loop in BASH is something like below:
            
            ```plaintext
            while [ condition ];
            do
                # statements
                # commands
            done
            ```
            
        * Creating a While Loop in Shell Script
            
            `i=0`  
            `while [ $i -le 10 ]`
            
            `do`
            
            `echo True`
            
            `((i++))`
            
            `done`
            
            `echo False`
            
        * Infinite While Loop in Shell Script
            
            `while :; do echo Script ran $i times; ((i++)); done`
            
              
            **Refer:-** [https://www.geeksforgeeks.org/bash-scripting-while-loop](https://www.geeksforgeeks.org/bash-scripting-while-loop/)
            
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682926510637/f6b2357f-e654-43e4-a95d-fb38bcb44476.png align="center")
        
        ### **<mark>Case Statements</mark>**
        
        **Syntax:**
        
        ```plaintext
        case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
        ```
        
        **Syntax:**  
        `case $variable in`  
        `pattern-1)`  
        `commands;;`
        
        `pattern-2)`  
        `commands;;`  
        `pattern-3)`  
        `commands;;`  
        `pattern-N)`  
        `commands;;`  
        `*)`  
        `commands;;`  
        `esac`
        
        **Code:**  
        `#!/bin/bash`  
        `echo "Which color do you like best?"`  
        `echo "1 - Blue"`  
        `echo "2 - Red"`  
        `echo "3 - Yellow"`  
        `echo "4 - Green"`  
        `echo "5 - Orange"`  
        `read color;`  
        `case $color in`  
        `1) echo "Blue is a primary color.";;`  
        `2) echo "Red is a primary color.";;`  
        `3) echo "Yellow is a primary color.";;`  
        `4) echo "Green is a secondary color.";;`  
        `5) echo "Orange is a secondary color.";;`  
        `*) echo "This color is not available. Please choose a different one.";; esac`
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682931158425/81333039-885e-4e7f-bf18-7211ee8d7c51.png align="center")
        
        ### <mark>Functions</mark>
        
        Function is a command in linux which is used to create functions or methods.  
        Function is a reusable block of code. Often we put repeated code in a function and call that function from various places. Library is a collection of functions. We can define commonly used function in a library and other scripts can use them without duplicating code.  
          
        When to us functions:  
        • Break up large script that performs many different tasks:  
        • Installing packages  
        • Adding users  
        • Configuring firewalls  
        • Perform Mathematical calculations  
          
        **<mark>Bash Function Syntax</mark>**  
        
        There are two different ways to declare a bash function:  
        
        1\. The most widely used format is:
        
        ```plaintext
        <function name> () { 
                <commands> 
        }
        ```
        
        Alternatively, the same function can be one line:
        
        ```plaintext
        <function name> () { <commands>; }
        ```
        
        2\. The alternative way to write a bash function is using the reserved word `function`:
        
        ```plaintext
        function <function name> {
                <commands>
        }
        ```
        
        Or in one line:
        
        ```plaintext
        function <function name> { <commands>; }
        ```
        
        Following example shows the use of the function −
        
        ```plaintext
        #!/bin/sh
        
        # Define your function here
        Hello () {
           echo "Hello World"
        }
        
        # Invoke your function
        Hello
        ```
        
          
        `function add() {   sum=$(( $1 + $2 ))   echo $sum   }   result=$(add 3 5)   echo "The result is $result"`  
          
          
        `add_user()`  
        `{`  
        `USER=$1 #Argument 1`  
        `PASS=$2 #Argument1 2`
        
        `useradd -m -p $PASS $USER && echo "Successfully added user"`
        
        `}`
        
        `#MAIN #Calling Function`
        
        `add_user devops test123`  
          
        **<mark>Refer:</mark>** [https://phoenixnap.com/kb/bash-function](https://phoenixnap.com/kb/bash-function)
        
    
    ### Arithmetic Operators
    
    * <mark>+</mark> (Addition)  
        `a=10 ; b=20 ; expr $a + $b`
        
    * <mark>-</mark> (Subtraction)  
        `a=10 ; b=20 ; expr $a - $b`
        
    * <mark>*</mark> (Multiplication) :- The `*` should be escaped as `\*` for multiplication using `expr` statement.  
        `a=10 ; b=20 ; expr $a \* $b`
        
    * <mark>/</mark> (Division)  
        `a=10 ; b=20 ; expr $b / $a`
        
    * <mark>% </mark> (Modulus)  
        `a=10 ; b=20 ; expr $b % $a`
        
    * <mark>=</mark> (Assignment) :- Assigns the right operand to the left operand  
        `a=10 ; b=20 ; expr $b % $a`
        
    * <mark>==</mark> (Equality) :- Compares two numbers, if both are the same then returns true.  
        `a=10 ; b=20 ; [ $a == $b ] ; echo $?`
        
    * <mark>!=</mark> (Not Equality) :- Compares two numbers, if both are different then returns true.  
        `a=10 ; b=20 ;[ $a != $b ] ; echo $?`
        
        <mark>Note:-</mark> `Make sure you have space before and after the Arithmetic Operators when using expr cmd.`
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682909599479/6c789d06-c9ae-47d3-9cfa-031eea79f668.png align="center")
        
    
    **Double parentheses:**  
    `echo $(( a + b )) echo $(( a-b )) echo $((a/b)) echo $(( a * b ))`
    
    Code 1:-  
    `A=20 B=10 echo "Sum is $(( A + B))" echo "Difference is $(( A - B))" echo "Product is $(( A * B))" echo "Quotient is $(( A / B))"`
    
    Code 2:-  
    `A=20`  
    `B=10`
    
    `echo "Sum is $(expr $A + $B)"`
    
    `echo "Difference is "$(expr $A - $B)`
    
    `echo "Product is "$(expr $A * $B)`
    
    `echo "Quotient is $(expr $A / $B)"`
    
    Code 3:-  
    `num1=$1 num2=$2 num3=$3 sum=$(( num1 + num2 + num3 )) average=$(echo "$sum / 3" | bc -l) echo $average`
    
    ### **Relational Operators**
    
    * <mark>-eq</mark> :- Checks if the value of two operands **is equal** or not; if yes, then the condition becomes true.  
        `a=10 ; b=20 ; [ $a -eq $b ] ; echo $?`
        
    * <mark>-ne</mark> :- Checks if the value of two operands are equal or not; if values are **not equal**, then the condition becomes true. \[ $a -ne $b \]
        
    * <mark>-gt</mark> :- Checks if the value of the left operand is **greater than** the value of right operand; if yes, then the condition becomes true. `[ $a -gt $b ]`
        
    * <mark>-lt</mark> :- Checks if the value of the left operand is less than the value of right operand; if yes, then the condition becomes true. `[ $a -lt $b ]`
        
    * <mark>-ge</mark> :- Checks if the value of the left operand is greater than or equal to the value of the right operand; if yes, then the condition becomes true. `[ $a -ge $b ]`  
        <mark>-le</mark> :- Checks if the value of the left operand is less than or equal to the value of the right operand; if yes, then the condition becomes true.  
        `[ $a -le $b ]`
        
    
    ### Boolean Operators
    

* <mark>! </mark> :- This is logical **negation**. This inverts a true condition into false and vice versa. `[ ! false ]` is true.
    
* <mark>-o</mark> :- This is logical **OR**. If one of the operands is true, then the condition becomes true. `[ $a -lt 20 -o $b -gt 100 ]` is true.
    
* <mark>-a</mark> :- This is logical **AND**. If both the operands are true, then the condition becomes true otherwise false. `[ $a -lt 20 -a $b -gt 100 ]` is false.
    

### String Operators

* <mark>=</mark> :- Checks if the value of two operands are equal or not; if yes, then the condition becomes true. `[ $a = $b ]` is not true.
    
* <mark>!=</mark> :- \[Not Equal to\] Checks if the value of two operands are equal or not; if values are not equal then the condition becomes true. `[ $a != $b ]` is true.
    

### Special Variables

<mark>$0</mark> :- The filename of the current script.

<mark>$n</mark> :- These variables correspond to the arguments with which a script was invoked. Here n is a positive decimal number corresponding to the position of an argument (the first argument is $1, the second argument is $2, and so on).

<mark>$#</mark> :- The number of arguments supplied to a script.

<mark>$*</mark> :- All the arguments are double quoted. If a script receives two arguments, $\* is equivalent to $1 $2.

<mark>$@</mark> :- All the arguments are individually double quoted. If a script receives two arguments, $@ is equivalent to $1 $2.

<mark>$?</mark> :- The exit status of the last command executed.

<mark>$$ </mark> :- The process number of the current shell. For shell scripts, this is the process ID under which they are executing.

<mark>$!</mark> :- The process number of the last background command.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682787562626/6fe43eff-1edc-4867-8d6d-a2c6814b9527.png align="center")

**Few Shell Substitutions**:

**<mark>Note:</mark>**<mark>-</mark> `-e` option enables the interpretation of backslash escapes.

`a=10 ; echo -e "Value of a is $a \t .... \t ... \v ...."`

`\v` vertical tab  
`\t` horizontal tab  
`\n` new line

**<mark>Conditional Operators</mark>**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913353334/74aa1421-de2a-4903-84e1-3b582ac57137.png align="center")

**Double Square Brackets:-**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913856374/e0eec638-a1a3-4d36-83e2-138b49fff641.png align="center")

**<mark>AND</mark>** and **<mark>OR </mark>** Operators

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913686852/a9076669-1736-46be-8822-249f70af7e24.png align="center")

**<mark>File Operators</mark>**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682913806180/885da23a-6447-43ff-bc9b-202c0503b22d.png align="center")

**<mark>Conditional Statements:</mark>**  
There are total 5 conditional statements that can be used in bash programming

1. if statement
    
2. if-else statement
    
3. if..elif..else..fi statement (Else If ladder)
    
4. if..then..else..if..then..fi..fi..(Nested if)
    
5. switch statement
    

Their description with syntax is as follows:

**<mark>if statement</mark>**  
This block will process if the specified condition is true.  
***Syntax:***

```plaintext
if [ expression ]
then
   statement
fi
```

**<mark>if-else statement</mark>**  
If the specified condition is not true in if part then else part will be execute.  
***Syntax***

```plaintext
if [ expression ]
then
   statement1
else
   statement2
fi
```

**<mark>if..elif..else..fi statement</mark> (Else If ladder)**  
To use multiple conditions in one if-else block, then elif keyword is used in shell. If expression1 is true then it executes statement 1 and 2, and this process continues. If none of the condition is true then it processes else part.  
***Syntax***

```plaintext
if [ expression1 ]
then
   statement1
   statement2
   .
   .
elif [ expression2 ]
then
   statement3
   statement4
   .
   .
else
   statement5
fi
```

**<mark>if..then..else..if..then..fi..fi..</mark>(Nested if)**  
Nested if-else block can be used when, one condition is satisfies then it again checks another condition. In the syntax, if expression1 is false then it processes else part, and again expression2 will be check.  
***Syntax:***

```plaintext
if [ expression1 ]
then
   statement1
   statement2
   .
else
   if [ expression2 ]
   then
      statement3
      .
   fi
fi
```

**<mark>Switch statement</mark>**  
<mark>case </mark> statement works as a switch statement if specified value match with the pattern then it will execute a block of that particular pattern  
When a match is found all of the associated statements until the double semicolon (;;) is executed.  
A case will be terminated when the last command is executed.  
If there is no match, the exit status of the case is zero.

***Syntax:***

```plaintext
case  in
   Pattern 1) Statement 1;;
   Pattern n) Statement n;;
esac
```

**<mark>Exit Codes</mark>**  
  
When a script or process exits or is terminated by some other means, it will have an exit code, which gives some indication about how or why the script or process ended.  
For example, an exit code of `0` means that the process **exited** without error – in other words, it completed its task and exited as expected. On the other hand, an exit code of `1` means that the process encountered some kind of error upon exiting.  
  
**How to get the exit code of a command**  
You need to use a particular shell variable called <kbd>$?</kbd> to get the exit status of the previously executed command.  
  
i.e  
`date   echo $?   date-foo-bar   printf '%d\n' $?`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682938001267/0d22982e-a2b3-4d21-8c0b-502e79693b6d.png align="center")

**<mark>How to use exit codes in scripts</mark>**  
  
**Syntax:**

```plaintext
exit [n]
```

To use exit codes in scripts an `if` statement can be used to see if an operation was successful.

```plaintext
#!/bin/bash

cat file.txt 

if [ $? -eq 0 ]
then
  echo "The script ran ok"
  exit 0
else
  echo "The script failed" >&2
  exit 1
fi
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682937118045/a985be75-23a6-4b24-a49f-07e237bf553b.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682937470888/66b95b6d-5deb-45d1-8613-f689ccb0d6ab.png align="center")

**Additional** :  
\-n string is not null.  
\-z string is null, that is, has zero length

* You can use the below Tools while working on your scripting/coding
    
    * **SHELLCHECK**  
        \[Install\]  
        `$ apt-get install shellcheck`  
        O  
        `$ yum install shellcheck`
        
        `$ shellcheck <shellscript.sh>`
        
    * **vim / vi**
        
    * **Pycharm**
        
    * **Visual studio code** (VS Code)
        
        **\[Refer\] Google Shell Style Guide** [https://google.github.io/styleguide/shellguide.html](https://google.github.io/styleguide/shellguide.html)
