Skip to main content

Learn Linux

Chapter #6: Getting Started with Bash Scripting

In this chapter, learn Bash scripting essentials: automate commands, handle environment variables, and apply shell expansion and substitution.

In this chapter, you'll take your first steps into shell scripting with Bash, which is one of the most powerful tools in a Linux user's toolkit.

You'll learn how to write your own scripts to automate tasks, work with environment variables, perform variable substitution, and understand how shell expansion works behind the scenes.

In this chapter, you'll learn how to:

  • Write basic and advanced shell scripts using Bash
  • Use and manage environment variables
  • Perform variable substitution to make scripts dynamic
  • Understand and apply shell expansion techniques
  • Practice your skills with hands-on exercises and real-world examples

By the end of this chapter, you'll not only be writing scripts, but also confidently debugging and experimenting with your own automation.

Let's get scripting!

Getting Started with Shell Scripts

In simple words, a shell script is nothing less and nothing more than a plain text file. Thus, it can be created and edited using our preferred text editor. We will use vim in the following examples, but you may choose whatever one you like.

Type:

vim myscript.sh

and press Enter.

The Shebang Line

The very first line of a shell script must be as follows (also known as a shebang):

#!/bin/bash

It β€œtells” the operating system the name of the interpreter that should be used to run the text that follows.

Writing Your First Script

Now it’s time to add our commands. We can clarify the purpose of each command, or the entire script, by adding comments as well. Note that the shell ignores those lines beginning with a pound sign # (explanatory comments).

#!/bin/bash
DATE=$(date +%Y-%m-%d)
echo "I am learning shell scripting"
echo "Today is $DATE"

In line #2, we create a variable named DATE with the contents of the command enclosed within $(). This syntax tells Bash to run whatever command we specify between $() and assign the output to the variable.

Once the script has been written and saved, we need to make it executable:

chmod +x myscript.sh

Understanding the $PATH Environment Variable

Before running our script, we need to say a few words about the $PATH environment variable, a special kind of variable that is available from the moment you log in using a console or a terminal.

If we run:

echo $PATH

from the command line, we will see the contents of $PATH: a colon-separated list of directories that are searched when we enter the name of an executable program.

It is called an environment variable because it is part of the shell environment - a set of information that becomes available for the shell and its child processes when the shell is first started.

When we type a command and press Enter, the shell searches in all the directories listed in the $PATH variable and executes the first instance that is found.

Script Execution and $PATH Priority

If there are two executable files with the same name - one in /usr/local/bin and another in /usr/bin - the one in the first directory will be executed first, whereas the other will be disregarded.

If we haven’t saved our script inside one of the directories listed in the $PATH variable, we need to prepend ./ to the file name in order to execute it:

./myscript.sh

Otherwise, we can run it just as we would do with a regular command:

myscript.sh

Flow Control

Whenever you need to specify different courses of action to be taken in a shell script as a result of the success or failure of a command, you will use the if construct to define such conditions. Its basic syntax is:

if CONDITION; then 
    COMMANDS
else
    OTHER-COMMANDS 
fi

Where CONDITION can be one of the following (only the most frequent conditions are cited here) and evaluates to true when:

[ -a file ]      # file exists
[ -d file ]      # file exists and is a directory
[ -f file ]      # file exists and is a regular file
[ -u file ]      # file exists and its SUID bit is set
[ -g file ]      # file exists and its SGID bit is set
[ -k file ]      # file exists and its sticky bit is set
[ -r file ]      # file exists and is readable
[ -s file ]      # file exists and is not empty
[ -w file ]      # file exists and is writable
[ -x file ]      # file exists and is executable

[ string1 = string2 ]      # strings are equal
[ string1 != string2 ]     # strings are not equal

# Integer comparisons:
[ int1 -eq int2 ]    # equal
[ int1 -ne int2 ]    # not equal
[ int1 -lt int2 ]    # less than
[ int1 -le int2 ]    # less than or equal
[ int1 -gt int2 ]    # greater than
[ int1 -ge int2 ]    # greater than or equal