A Guide to Bash

A Guide to Bash

Bash is an application

What is Bash?

Bash is a command-line interface shell program used extensively in Linux and macOS. The name Bash is an acronym for “Bourne Again Shell,” developed in 1989 as a successor to the Bourne Shell.

“What’s a shell?” you ask? A shell is a computer program that allows you to directly control a computer’s operating system (OS) with a graphical user interface (GUI) or command-line interface (CLI).

You actually use GUI shells all the time. For example, Windows 10 is based on the Windows shell that allows you to control your OS with a desktop, taskbar, and menus.

Advantages of Bash

One of the biggest advances in computer software development was the introduction of windows and menus, so what’s the point of going back? People use CLIs like Bash because they still have a few distinct advantages over GUIs. Let’s explore some of these advantages.

Access your operating system more efficiently

People use Bash when they want to control their computer or OS without having to navigate menus, options, and windows within a GUI. As we pointed out earlier, with CLIs like Bash, you usually don’t even need to use your mouse. You can navigate through your computer’s OS without your fingers ever leaving your keyboard.

For example, if you want to quickly create, edit, or delete multiple files, it’s easier to use Bash instead of finding each file by pointing and clicking on multiple directories.

Plus, using Bash instead of a GUI is less resource-intensive since your computer doesn’t need to dedicate resources to rendering graphical output. This makes Bash an attractive option when you’re already running multiple programs, a virtual machine, or otherwise have limited computing resources to work with.

On Linux and Unix (such as BSD and macOS), most commands are stored by default in system directories like /usr/bin and /bin. By nature, Bash doesn't know these commands any more than you naturally know Klingonese, but just as you can look up Klingon words, Bash can look up commands. When you issue a command to Bash, it searches specific directories on your system to see whether such a command exists. If the command does exist, then Bash executes it.

Bash is also a command, and it's usually the default command executed when you open a terminal window or log into a text console. To find out where any command is located on your system, Bash included, you can use the which command in a terminal:

which bash

Overview

This article will explain how to use Bash by creating and using the following data types or techniques:

  • Outputting Statements

  • Creating Strings

  • Declaring Variables

  • Integers or Floats

  • Printing Saved Variable Data

  • Clearing the Terminal

  • Navigating through the Terminal

  • Making and Deleting Directories or Folders

  • Making and Deleting Files or Scripts

  • Editing, Executing and Writing Scripts

    • Making Comments

    • Conditionals

      • If, Elif, Else statements

      • Nested If Functions

      • For Loops

      • While Loops

    • Functions

    • Deleting Entire Lines in a Script

Let's jump into our Terminal

How to Output Statements

Statements are outputted by using the "echo" command.

echo "Quoted words are going to print on the terminal"

Creating Strings

As shown above, in the first example, a statement enclosed within single quotes '' or double quotes "", is considered a string.

# Using echo to Output Statements
echo "Hello. This is another statement."

Declaring Variables

A variable can be declared by assigning a letter or word to a statement.

# declaring a variable
variable="This is a variable"

After executing the file it will print the text stored into that variable

Notice, there cannot be any spaces between the variable name, the equal sign, and what data the variable holds.

Integers or Floats

Numbers such as integers or floats are another data type that can be declared. Assign a variable to a number for it to contain number data.

The difference between an integer and a float is, an integer is a whole number such as 0, 1, 2, or 3 .... while floats are decimal numbers such as 0.6, 1.3, 2.2, 3.1. A float can be declared similarly as an integer.

# Create a Variable that holds an Integer & Float
a=15
b=1.4

Printing Saved Variable Data

Variables that are once saved such as "make_a_variable", "a", and "b" can be printed out with echo and placing a "$" before the variable name as shown below:

echo $variable

echo $a

echo $b

Placing a $ before the variable name will print the content the variable holds.

Variable naming conventions

In Bash scripting, the following are the variable naming conventions:

  1. Variable names should start with a letter or an underscore (_).

  2. Variable names can contain letters, numbers, and underscores (_).

  3. Variable names are case-sensitive.

  4. Variable names should not contain spaces or special characters.

  5. Use descriptive names that reflect the purpose of the variable.

  6. Avoid using reserved keywords, such as if, then, else, fi, and so on as variable names.

Here are some examples of valid variable names in Bash:

name
count
_var
myVar
MY_VAR

And here are some examples of invalid variable names:

2ndvar (variable name starts with a number)
my var (variable name contains a space)
my-var (variable name contains a hyphen)

Following these naming conventions helps make Bash scripts more readable and easier to maintain.

Clearing the Terminal

If any commands are entered in the Terminal, it stays there. To erase those commands, perform "clear" and press enter.

clear

Navigating through the Terminal

Before making files, it is preferred to create files in different folders or what is normally referred to as directories to be organized. Any existing files in the current directory can be seen by using the directory or 'dir' command.

To make a folder or directory in the Terminal, use the "mkdir" command. Any name can be given to it.

mkdir folder_name

To make more than one folder at a time, make sure to have spaces between each folder name and Bash will create many folders at once.

mkdir folder_name1 folder_name2 folder_name3

To delete any unwanted folders or directories, use the "rmdir" command.

rmdir folder_name

To delete more than one folder at a time, make sure to have spaces between each folder name and Bash will delete the folders as specified:

rmdir folder_name1 folder_name2

Be careful specifying what folders are deleted since the Terminal instantly deletes what is specified.

To change directories, use the change directory or "cd" command alongside the name of the folder to enter the directory.

As shown below, the command dir was used to first show which files and folders are in each directory, and then the commands "cd Documents" and "cd Scripts" are used to first enter the Documents directory and then enter the Scripts directory that was created beforehand.

To enter a directory that the Terminal was previously in, use the "cd .." command to previously go back one directory

cd ..

To go to the home directory, use the "cd ~" command. The home directory is the default or starting directory when opening up the Terminal

cd ~

To go to any directory, use the "cd specify_entire_path_directory"

cd specify_entire_path_directory

The print working directory or "pwd" command shows the full path of the current directory. Every path should be written in the following format as shown by "pwd":

Making Files or Scripts

Below shows the current files in the Documents/Scripts directory by using the "dir" command. If there are no files, then nothing will appear.

A Bash script in the Terminal can be created by using the 'touch' or 'vim' command. 'vim' is used to edit the file after it was created, but it can also create the file if it does not exist. When making a file, the name of the file and also its extension can be created at the same time. To run a bash script, the .sh extension is needed.

If the touch command is used again to recreate the file, the command will execute and the file will not be overwritten.

Deleting Files or Scripts

If a new file with an unwanted name is created, it can be removed by using the rm command:

rm file_name

To delete more than one file name, make sure to have spaces between each file name similar to deleting many folders at once, and Bash will delete the files as specified:

rm file_name1 file_name2 file_name3

Be careful specifying what files are deleted since the Terminal instantly deletes what is specified.

Editing, Executing and Writing Files or Scripts

A file can be edited or created if it does not exist with the "vim" command.

After using "vim", a text editor appears:

To start inserting in vim editor, first type "i" to make it insert mode.

At the beginning of every script, a shebang is written to tell the Terminal that it is fully aware it is running a Bash script. The shebang can be declared by writing:

#!/bin/bash

Making Comments

In Bash, comments can be created by placing a '#' anywhere in the script. While comments are never executed when a bash script is run, comments are useful as they are used to write notes in a script to explain why another line of code is necessary.

# A comment is made by using a '#' and then writing some notes after the '#'
# This is an example comment

To save and exit the script, type "esc" then ":" then "wq" (W= write and Q= quit) and "Enter".

Executing Scripts

To execute a script, type the word "bash" and the name and its file extension following it:

bash file_name.sh
or 
./file_name.sh

After running the script, nothing happened since the contents in this file only include comments. Once again, comments are not printed out when a script is run.

Conditionals

Conditionals are often used to verify statements, below are a few keywords that are used with either the string or integer key type:

And: &&

Or: ||

Conditions to use with Numbers

-eq: Equal to

-gt: Greater than

-ge: Greater or equal to

-lt: Less than

-le: Less than or equal to

-ne: Not equal

Conditionals to use with Strings

">" : Greater than

"<" : Less than

\= : Equal to

!= : Not equal to

If, Elif, Else, Statements

Conditionals are often used with and to verify statements, and one type of statement is an if-statement.

If-Statement

#!/bin/bash

if [ 3 -gt 2 ]
then
        echo "True"
fi

  • "..." is a placeholder for a statement to be there

  • Bash is case and space sensitive with how any if statement is declared. First, "if" must be written, then hit space to enter a "[" and there must be a space between the variable or integer and the bracket, as shown with "[" and 3 and the rest of the entire statement. After finishing the statement, enclose it with the "]" bracket. "then" must be written on a new line or afterward write ";" next to the "]" bracket and "then" can be written on the same line. Within the if statement, hit "tab" to write the condition within the if statement. To close the if statement, the word "fi" is written on a new line.

If-Else Statement

To extend an if statement, an else statement can be added to print out an alternative statement if the statement that is being validated is not correct.

if [ 3 -gt 4 ]
then
        echo "True"
else
        echo "False"
fi

If-Elif-Else Statement

To check for many conditions without writing many separate if statements, many elif statements can be added. elif stands for else if. If the if-statement does not work, then an elif statement can be incorporated to check another statement. All of these statements begin with an if, in between have elif statements and the last statement is an else statement.

if [ 3 -gt 4 ]
then
        echo "False"
elif [ 3 -lt 4 ]
then
        echo "True"
else
        echo "Something went wrong."
fi

Using And, Or

The && symbol means and. The || symbol means or. These can also be used in verifying statements. For example, in an if-statement, is required to verify more than one condition is true, it is recommended to use the "&&" symbols.

if [ 3 -gt 2 ] && [ 2 -gt 1 ]
then
        echo "Both these statements are true"
fi

The "||" takes and reads many conditions, and will return a result if one of those conditions is true.

if [ 3 -gt 2 ] || [ 2 -gt 3 ]
then
    echo "True"
fi

While it is true 3 is greater than 2, it is also true 2 is not greater than 3. An or statement verifies that if at least one condition is true, in this case, 3 is greater than 2, it would print out what is specified in the "then" block.

Nested If Statements

A nested if-statement is including an if-statement within an if-statement. This is useful since in a normal if-elif-else statement, it will execute the first statement that is true and won't execute the other elif statements. Including an if-statement within an if-statement can be used if there was more code that needs to be run and verified only within the if-statement.

if [ 3 -gt 2 ] || [ 2 -gt 3 ]
then
        echo "True"

        if [ 3 -gt 1 ]
        then
                echo "This is true too"
        fi 

fi

For Loops

A for loop can searches through an entire variable and prints out long statements in a more readable way

just_a_string=("the [@]" "prints all words separated by spaces onto new lines")

for i in ${just_a_string[@]};
do
    echo $i
done

Not including the at sign will print the string as is.

A for loop can also print out many numbers within a specified range:

for i in {1..50..5}
do
    echo $i
done

While Loops

A while loop will always execute the statement as long as it is true. Using while loops is good to see how long the statement remains true, to exit out of the loop, it is recommended to either increase or decrease the variable to make the condition untrue and exit out of the while loop. To decrement or increment the variable, it must be placed within two parentheses.

i=3
while [ $i -gt 1 ]
do
        echo "The value of i is $i"
        ((i=i-1))
done

Functions

A function is declared by giving it a name, followed by a space, a parenthesis and a bracket. Within the brackets, code is written there. Instead of writing the same code over and over again to do a task, a function is recommended to hold that code to that desired task and call the function when needed.

function_name () {
        echo "You can write anything in here"
        echo "Write the name of the function at the end of the script, and it will execute"
}

function_name

Basic Bash commands (echo, read, etc.)

Here is a list of some of the most commonly used bash commands:

  1. cd: Change the directory to a different location.

  2. ls: List the contents of the current directory.

  3. mkdir: Create a new directory.

  4. touch: Create a new file.

  5. rm: Remove a file or directory.

  6. cp: Copy a file or directory.

  7. mv: Move or rename a file or directory.

  8. echo: Print text to the terminal.

  9. cat: Concatenate and print the contents of a file.

  10. grep: Search for a pattern in a file.

  11. chmod: Change the permissions of a file or directory.

  12. sudo: Run a command with administrative privileges.

  13. df: Display the amount of disk space available.

  14. history: Show a list of previously executed commands.

  15. ps: Display information about running processes.

How to Schedule Scripts using cron

Cron is a powerful utility for job scheduling that is available in Unix-like operating systems. By configuring cron, you can set up automated jobs to run on a daily, weekly, monthly, or specific time basis. The automation capabilities provided by cron play a crucial role in Linux system administration.

Below is the syntax to schedule crons:

# Cron job example
* * * * * sh /path/to/script.sh

Here, the *s represent minute(s) hour(s) day(s) month(s) weekday(s), respectively.

Below are some examples of scheduling cron jobs.

SCHEDULEDESCRIPTIONEXAMPLE
0 0 * * *Run a script at midnight every day0 0 * * * /path/to/script.sh
*/5 * * * *Run a script every 5 minutes*/5 * * * * /path/to/script.sh
0 6 * * 1-5Run a script at 6 am from Monday to Friday0 6 * * 1-5 /path/to/script.sh
0 0 1-7 * *Run a script on the first 7 days of every month0 0 1-7 * * /path/to/script.sh
0 12 1 * *Run a script on the first day of every month at noon0 12 1 * * /path/to/script.sh

Using crontab

The crontab utility is used to add and edit the cron jobs.

crontab -l lists the already scheduled scripts for a particular user.

You can add and edit the cron through crontab -e.

You can read more about corn jobs in my other article here.

How to Debug and Troubleshoot Bash Scripts

Debugging and troubleshooting are essential skills for any Bash scripter. While Bash scripts can be incredibly powerful, they can also be prone to errors and unexpected behavior. In this section, we will discuss some tips and techniques for debugging and troubleshooting Bash scripts.

Set the set -x option

One of the most useful techniques for debugging Bash scripts is to set the set -x option at the beginning of the script. This option enables debugging mode, which causes Bash to print each command that it executes to the terminal, preceded by a + sign. This can be incredibly helpful in identifying where errors are occurring in your script.

#!/bin/bash

set -x

# Your script goes here

Check the exit code

When Bash encounters an error, it sets an exit code that indicates the nature of the error. You can check the exit code of the most recent command using the $? variable. A value of 0 indicates success, while any other value indicates an error.

#!/bin/bash

# Your script goes here

if [ $? -ne 0 ]; then
    echo "Error occurred."
fi

Use echo statements

Another useful technique for debugging Bash scripts is to insert echo statements throughout your code. This can help you identify where errors are occurring and what values are being passed to variables.

#!/bin/bash

# Your script goes here

echo "Value of variable x is: $x"

# More code goes here

Use the set -e option

If you want your script to exit immediately when any command in the script fails, you can use the set -e option. This option will cause Bash to exit with an error if any command in the script fails, making it easier to identify and fix errors in your script.

#!/bin/bash

set -e

# Your script goes here

Troubleshooting crons by verifying logs

We can troubleshoot crons using the log files. Logs are maintained for all the scheduled jobs. You can check and verify in logs if a specific job ran as intended or not.

For Ubuntu/Debian, you can find cronlogs at:

/var/log/syslog

The location varies for other distributions.

A cron job log file can look like this:

2022-03-11 00:00:01 Task started
2022-03-11 00:00:02 Running script /path/to/script.sh
2022-03-11 00:00:03 Script completed successfully
2022-03-11 00:05:01 Task started
2022-03-11 00:05:02 Running script /path/to/script.sh
2022-03-11 00:05:03 Error: unable to connect to database
2022-03-11 00:05:03 Script exited with error code 1
2022-03-11 00:10:01 Task started
2022-03-11 00:10:02 Running script /path/to/script.sh
2022-03-11 00:10:03 Script completed successfully

Conclusion

In this article, we started with how to access the terminal and then ran some basic bash commands. We also studied what a bash shell is. We briefly looked at branching the code using loops and conditionals. Finally, we discussed automating the scripts using cron followed by some troubleshooting techniques.

Thank you so much for taking the time to read till the end! Hope you found this blog informative and helpful.

Feel free to explore more of my content, and don't hesitate to reach out if need any assistance from me or in case of you have any questions.

Happy Learning!

~kritika :)

Connect with me: LinkedIn