# It's about the Bash!


### Introduction

A bash script is a file having instructions that can also be executed individually on a command line. With scripting, you can automate repetitive tasks. To create a bash script, you can start by creating a file in your favorite editor & saving it with the `.sh` extension. 

#### Shebang (#!)

The first line in every bash script is the shebang character, which tells the operating system which interpreter to use to parse the rest of the code. The shebang takes the following form,

```bash
#!interpreter [arguments]
```

Where, the interpreter is full path to the binary file & arguments are optional.

| Interpreter         | Description                                          |
| ------------------- | ---------------------------------------------------- |
| #!/bin/bash         | uses `bash` to parse the file                        |
| #!/usr/bin/env bash | uses `env` to find the path of the `bash` executable |

#### Executing the Script

The bash script can be executed in two ways, either by sourcing the file itself or by creating an executable. The way we can do it is as mentioned below, 

- By sourcing the file itself

```bash
source bash-refresher.sh
```

- By creating an executable

```bash
chmod +x bash-refresher.sh
./bash-refresher.sh
```

### Printing

Bash uses `echo` to display the argument passed to the command.  

```bash
#!/usr/bin/env bash

echo "Hello, World!"
```


###  Commenting 

Commenting plays very important role in programming, so that the developer can understand why a particular block of code was written. In bash, there are multiple ways in which you can comment your code. 

#### Single line comments

Anything followed by the `#` hash character is skipped, this way you can write single line comment in bash.

```bash
# This is one-liner comment
```

#### Multi line comments

Multi-line comments in bash can be written using the `:` bash operator and `' '` pair of single quotes.

```bash
: '
This is a way one can write multi line comments in bash.
echo "This will not be echoed!"
'
```

### Variables

You can define variables in bash using the `=` assignment operator and can use the `$` dollar sign to access the variable. 

>The assignment operator should not have space on either side while defining a variable

```bash
#!/usr/bin/env bash

language="bash"
echo "This article is about the $language scripting"

```

### Reading Input 

To read input from the user you can use `read`  command. To add a prompt , one can use the `-p` flag followed by the prompt string, whereas to read the input silently one can use the `-s` flag. The value entered by the user, is assigned to the variable name following the read command.

```bash
#!/usr/bin/env bash

read -p "Enter username:	" username
read -sp "Enter password: 	" password
```

You can access the value entered by the user, using the `$` dollar sign followed by the variable name.

### Conditional Statements

You can define conditional statements in bash using `if-elif-else-fi` block. The conditions must be passed in single `[ ]` or double square`[[ ]]` brackets. In bash we use the `then` keyword to execute the block of code, when a certain condition returns `True`.

> Leave a space before and after the end of the condition statement inside the square brackets [[ condition ]]

- Syntax for if-statements

```bash
if [[ condition ]]
then
    <statements>
elif [[ condition ]]
then
    <statements>
else
    <statements>
fi
```

- Example for if-statements

The condition flags are listed at the end of the article, also you can use the logical operators to chain conditions.

```bash
#!/usr/bin/env bash

echo -p "Please enter your age: " age

if [[ -z $age || $age -le 0 ]]; 
then
  echo "Please enter valid age! o_O"
  
elif [[ $age -gt 0 && $age -lt 21 ]]; 
then
  echo "we're young! \o/"
  
elif [[ $age -eq 21 ]]; 
then
  echo "we're forever 21! :D"
  
else
  echo "we're just not 21 anymore! :("

fi

```




### Case Statements

Case statements in bash are similar to switch cases in other programming languages. If a particular condition is matched, the statement block for that case is executed. If no case is matched the default statement  is executed.

- Syntax for case-statements

```bash
case variable in 
    case_condition )
     	statements
    ;;
*)
	default_statements
esac
```

> semi-colon `;` indicates the end of the command & beginning of a new one. The asterisk `*` defines the default case

- Example for case-statements

```bas
#!/usr/bin/env bash

read -p "Joey doesn't share food! [True|False] ?" input

case $input in
  "True")
  echo "Right! \o/"
  ;;
  "False")
  echo "Oh my God! o_O"
  ;;
  * )
  echo "Invalid Choice!"
esac

```

### Loops

Similar to other languages, bash also supports the `while` and the `for` loops. The statements to be executed must be enclosed within the `do-done` block. 

#### For Loop

- Syntax - for loop

```bash
for iterable in iterables
    do
        <statements>
    done
```

- Example - for loop

In this example, we are iterating over an array of strings, to access the element we use `"${array[@]}"` as iterables.

```bash
#!/usr/bin/env bash

friends=("Joey" "Chandler" "Ross")
for friend in "${friends[@]}"
do
	echo "Hi I'm $friend"
done
```

#### While Loop

- Syntax - while loop

```bash
while condition
    do
        <statements>
    done
```

- Example - while loop

In this example, we have a while loop that would be executed until a valid password is entered. 

> ​	The `-z` flag checks if the value is empty

```bash
#!/usr/bin/env bash

while [ -z $INPUT ]
do
  echo -e "Enter new password.Password should not be blank"
  read -s INPUT
done

```

### Functions

Functions are reusable blocks of code. In bash, you can define a function in two ways, by typing `function_name()` or using the `function` keyword.

A function can take no arguments or can have multiple arguments passed as command-line arguments. Command line arguments can be accessed using the `$` dollar sign and indexes starting at 1,  like `$1` for the first argument, `$2` for the second, and so on.

Unlike other languages, one does not have to call the function in bash using empty parenthesis, simply typing the `function_name` works.

- Syntax for functions

```bash
function function_name() {
    <statements>
}

# calling a function
function_name
```

- Example of functions

In the example, we have two functions, one that takes no arguments and second one that takes two command line arguments & display it as a conversation.

```bash
#!/usr/bin/env bash

function joey_tribbiani(){
  echo "How you doin'?"
}

trained_for_nothing(){
  echo "$1 : You got a job?"
  echo "$2 : Are you kidding? I'm trained for nothing!"
}

joey_tribbiani
trained_for_nothing Ross Rachel

```

### Extras

#### Bash Expansions

- Command Substitution `$(command)`

  This allows user to execute a command in subshell & replace the command substitution with the output of the command enclosed. Another way to do this is by enclosing command within back ticks.

  ```
  `command`
  ```

- Arithmetic Expansion `$(( expression ))`

  This allows user to evaluate the expression and replace it with the result of the expression enclosed.

- Parameter Expansion `${parameter}`

  This allows user to access the value of the parameter and replace it.

#### Built-in Variables

Bash has few builtin variables that are very useful while writing a bash script. The table below shows the variable and its description. Remember that the `$` dollar sign is used to access the variable in bash.

| Variable | Description                                         |
| :------: | --------------------------------------------------- |
|   `$#`   | Total number of arguments passed                    |
|   `$@`   | Values of the arguments passed                      |
|   `$?`   | Execution status of the last command, 0 for success |
|   `$*`   | Values of the arguments passed                      |

> The difference between `$@` and `$*` is that, if you pass them inside quotes as a string, `*` takes all the positional arguments as a single parameter whereas `@` will pass each positional argument separately

#### File Conditions

Below table gives list of few operators that can be used to test a particular property of a file.

| Flag      | Description                                      |
| --------- | ------------------------------------------------ |
| -d string | Returns True if the string is a directory        |
| -f string | Returns True if the string is file               |
| -g file   | Returns True if the group-id is set on the file  |
| -u file   | Returns True if the user-id is set on the file   |
| -r file   | Returns True if the file is readable             |
| -w file   | Returns True if the file is writable             |
| -x file   | Returns True if the file is executable           |
| -s file   | Returns True if the size of the file is non-zero |

#### Comparison Operators

Below table gives list of few of the comparison operators available in bash.

| Operator      | Description                                               |
| ------------- | --------------------------------------------------------- |
| val1 -eq val2 | Returns True if the values are equal                      |
| val1 -ne val2 | Returns True if the values are not equal                  |
| val1 -gt val2 | Returns True if the val1 is greater than val2             |
| val1 -ge val2 | Returns True if the val1 is greater than or equal to val2 |
| val1 -lt val2 | Returns True if the val1 is less than val2                |
| val1 -le val2 | Returns True if the val1 is less than or equal to val2    |

#### Exit Commands

There are two commands that work as exit commands with different purposes, the `exit` and the `return` command

| Command | Purpose                     |
| ------- | --------------------------- |
| exit    | Exit from the bash script   |
| return  | Exit from the bash function |

### Conclusion
Having bash knowledge plays a key role if you use Linux in your day-to-day work. I hope this article, helps you refresh your bash skills. 

Thanks for reading 🙇🏻‍♂️

### References

- [Ryan Tutorials](https://ryanstutorials.net/bash-scripting-tutorial/)

- [Bash Reference Manual](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html)

  
