Learn Shell Scripting in 5 Minutes
Tags: bash, terminal, shell, scripting
Published: 2020-07-17 00:24:04

---
title: Learn Shell Scripting in 5 Minutes
published: true
description: 
tags: Bash, Terminal, Shell, Scripting
//cover_image: https://direct_url_to_image.jpg
---

**Table of Contents**
1. Getting Started
2. Comments
3. Variables
4. Loops
5. Conditionals
6. Case
7. Functions
8. User Input
9. Arithmetic
10. Arrays
11. Debugging Shell scripts
12. Tips and Tools

-------------------------------------------------------------

**Getting Started**

Create a text file called *script* with a *.sh* file extension (not required) and add the contents below to it.
```
#!/bin/bash
echo "Hello, World!"
```
You have to make the shell script you just created executable by running this:
`sudo chmod +x script.sh`

Now you can run the script to see the message printed to the screen with 
`source script.sh`
```
Hello, world!
```
-------------------------------------------------------------

**Comments**

Like all other programming languages, you can add comments in your scripts to describe exactly what your script does. Bash scripts support single line and multi-line comments.

*Single line comments*
```
#!/bin/bash
# This is a single line comment
echo "Hello, world!"
```

*Multi-line comments*
```
#!/bin/bash
: '
This is a multi-line comment
spanning not just one line
but many lines
'
echo "Hello, world!"
```

-------------------------------------------------------------

**Variables**
There are two types of variables in Bash,
* User-defined variables: are variables defined by a user in the shell script and are usually in all lowercase.
```
#!/bin/bash
message="Shell scripting tutorial"
echo $message
```
* Shell defined variables: are variables defined by the Bash shell and are usually in all uppercase.
```
#!/bin/bash
echo $BASH_VERSION
```
There are a number of builtin Bash variables:

$$ - PID of the current shell
$! - PID of last background command
$? - Exit status of the last command
$0 - Name of the current command
$1 - Name of the current command's first parameter
$9 - Name of current command's ninth parameter
$@ - All of the current command's parameters (preserving whitespace and quoting)
$* - All of the current command's parameters (not preserving whitespace and quoting)

**Formatting Variables**
```
# The string 'Not defined' is printed if the variable "message" has not been defined.
echo ${message:-"Not defined"}

# The string "Not defined but now defined and assigned", if the variable did not exist prior.
echo ${message:="Not defined but now defined and assigned"}


# The string "Error: the variable does not exist" is printed if you try to print a variable does not exist.
echo ${message:?"Error: the variable does not exist"}

var1='shell scripting'
var2='BASH SCRIPTING'
echo ${var1^^} # Print a variable in all uppercase.
echo ${var1^} # Convert the first letter to uppercase.
echo ${var2,,} # Print a variable in all lowercase.
echo ${var2,} # Convert the first letter to lowercase.
```

-------------------------------------------------------------

**Loops**

C-style for loops
```
#!/bin/bash

for ((i=0; i<10; i++))
do
    echo $i
done
```


Python style for loops
```
#!/bin/bash

for number in "1 2 3 4 5"
do
    echo $number
done
```

While loops
```
#!/bin/bash


count=0
while [[ $count -lt 10 ]]
do
    echo $count
    (( count++ ))
done
```

Until loops
```
#!/bin/bash

count=10
until [[ $count -eq 0 ]]
do
    echo $count
    (( count-- ))
done
```

Select loops
You can use select loops to create menu type interfaces to shell scripts.
```
#!/bin/bash

options="Yes No Maybe"
ps3="Select your option" # Customize your menu selection.

select option in $options
do
    if [[ $option == "Yes" ]]
    then
        echo "You chose Yes"
    elif [[ $option == "No" ]]
    then
        echo "You chose No"
        exit
    elif [[ $option == "Maybe" ]]
    then
        echo "You chose Maybe"
    else
        echo "Invalid option chosen"
        exit
    fi
done
```

-------------------------------------------------------------

*Conditionals*
Bash supports the usual **if, elif and else** conditional operators of other programming languages.

Supported Bash comparison operators are:
1. Integer comparison operators
2. String comparison operators
3. Compound comparison operators
4. File comparison operators



#### Integer comparison operators
-eq	is equal to

-ne	is not equal to

-gt	is greater than

-ge	is greater than or equal to

-lt	is less than

-le	is less than or equal to

<	is less than – place within double parentheses

<=	is less than or equal to

\>	is greater than

\>=	is greater than or equal to



#### String comparison operators
=	is equal to

==	is equal to

=	is not equal to

\<	is less than ASCII alphabetical order

\>	is greater than ASCII alphabetical order

-z	string is null (i.e. zero length)

-n	string is not null (i.e. !zero length)


#### Compound comparison operators
-a	logical and
-o	logical or




```
#!/bin/bash

a=1
b=2

if [[ $a -gt $b ]]
then
    echo $a is greater than $b
elif [[ $a -lt $b ]]
then
    echo $a is less than $b
elif [[ $a -eq $b ]]
then
    echo $a is equal to $b
else
    echo "unknown condition"
fi


[[ -e "$file" ]] # True if file exists
[[ -d "$file" ]] # True if file exists and is a directory
[[ -f "$file" ]] # True if file exists and is a regular file
[[ -z "$str" ]]  # True if string is of length zero
[[ -n "$str" ]]  # True is string is not of length zero
-r file has read permission
-w file has write permission
-x file has execute permission
file1 -nt file2	file file1 is newer than file2
file1 -ot file2	file file1 is older than file2
file1 -ef file2	files file1 and file2 are hard links to the same file

[[ ... ]] && [[ ... ]] # And
[[ ... ]] || [[ ... ]] # Or
```

**Case**
A Case statement can simplify and replace a collection of if elif else statements and it can also be used with the Select statement.

```
#!/bin/bash
read -p "Make your choice: " option
case $option in
    "Yes")
    echo "You chose 'Yes'";;
    "Maybe")
    echo "You chose 'Maye'";;
    "No")
    echo "You chose 'No'";;
    *) # default option
    echo "Unknown option";;
esac

# Create a Menu system with Select and Case

options="Yes No Maybe"
select option in $options
do
    case $option in
    "Yes")
    echo "You chose 'Yes'";;
    "Maybe")
    echo "You chose 'Maye'";;
    "No")
    echo "You chose 'No'"
    exit;;
    *) # default option
    echo "Unknown option";;
   esac
done
```

**Functions**
Functions in Bash work like in regular programming languages, the only difference is the invocation i.e. you execute a function by typing the name only with no brackets. Also, Bash functions do not have a return value.
```
#!/bin/bash

# Define a simple function
function greeter() {
    echo "Hello, world!"
}

# Define a function that accepts arguments
function greeter1() {
    echo $1
}
```

Call the function by running 
`greeter` to display:

```
Hello, World!"
```
And call the function by passing in arguments
`greeter Hello, world` to display:
```
Hello, World!"
```


**User input**
You can accept user input with Bash with the *read* keyword
```
#!/bin/bash
read var # The user inputted value is saved in a variable called *var*

read -p "Enter your name" name # A prompt "Enter your name" is displayed to the user and the supplied value is saved in the variable "name".

read -s -p "Enter your password" password # "This hides the user inputted value. Useful for password inputs.

read -p "Enter all your names" -a names # If you want to accept more than one value from users. It creates an Array object called *names*
```


**Arithmetic**
```
#!/bin/bash

a=1
b=2
$((a + b)) # Addition
$((a - b)) # Subtraction
$((a * b)) # Multiplication
$((a / b)) # Division
$((a % b)) # Modulus
```

If you want to do advanced arithmetic like dealing with floats, finding square roots of numbers, etc, you should use the inbuilt *bc* command.
```
#!/bin/bash
echo "scale=2; sqrt((49)) | bc -l # scale determines the number of decimal places.
echo "scale=3; 3.142 * 4.2" | bc -l
```



**Arrays**
In Bash, there are two kinds of variables
1. Scalar variables (contains a single value)
2. Arrays variables (contains multiple values)
Bash arrays are Zero-based arrays i.e. start from position zero.

```
#!/bin/bash

names=(Jack John Jill Scot)
${names[@]} # This prints all the variables
${#names[@]} # Counts the number of items in the *names* array.
${!names[@]} # Returns the indexes of the items in the array.
unset names[<index>] # Removes the item in the array at the specified index.
${names[0]} # Returns the first item of the array.
${names[-1]} # Returns the last item of the array.
```




**Tips, Tricks, and Tools**
1. Use shellcheck.net to find bugs in your shell scripts.
2. You can debug your shell scripts running it like
`bash -x script.sh`. This runs the script in debug mode.
3. You can set breakpoints in your shell scripts
```
#!/bin/bash

set -x
message="This is a shell scripting tutorial"
echo $message
set +x
```

So we have come to the end of this 5-minute introduction to Bash shell scripting. I hope it will start you on your journey to more mastery.