BASH Scripting for Beginners

All BASH scripts require a single line to be entered at the top of the script file.

#!/bin/bash

This single line tells the operating system what shell should be used to interpret the commands that will be following. For a quick working example lets start off with the same old boring generic "Hello World" program example.

#!/bin/bash
#Print "Ello Wurld!" to the console display
/bin/echo "Ello Wurld!"

Looking at the above script you'll notice three lines. The top line, as previously stated, tells the operating system what shell to use to interpret the code that will follow. The second line, starting with an octothorpe (also known as a hashtag or pound sign), is a comment.

Over time a scripts usage and use case can change. As these changes are made complexity is added and can eventually lead to unreadable code. It is a good practice to always comment your code. Yes, the example I give above may not be necessary due to the simplicity of the script.

Comments compliment your code and help soften the edges of complexity. Good comments enhance the usability and adaptability of your code. They also make it easy to comprehend from the perspective of anyone other than the original author.

Bottom line: Good commenting practices save on future grief. Whether that grief rests on the shoulders of the original author, or is transferred to others that have to interpret, alter, and/or replace your pre-existing code/scripts.

Fantastic! Now you've got your first basic script created and it is time to run it. Save the changes to the script file as ello-world.sh. From a root prompt we'll do the following command to make the shell executable:

user@rbiped:~/bash-scripts/ramblings/chmod +x ello-wurld.sh

The chmod +x command modifies the permissions of the script file and makes it executable. If you do a quick “ls” you might notice that it has changed colors. If you do a “ls -la” you’ll notice the execution bit has been set for the file. (that’s the extra “x” you see after all the “rw'” entries at the beginning of the lines below)

Before chmod +x:

user@rbiped:~/bash-scripts/ramblings# ls -la  
-rw-rw-r-- 1 ash ash 0 May 7 00:43 ello-wurld.sh

After chmod +x:

user@rbiped:~/bash-scripts/ramblings# ls -la  
-rwxrwxr-x 1 ash ash 0 May 7 00:43 ello-wurld.sh

Alright! We're ready! Let's run our script!

BASH scripts can be executed a few different ways.

  • If you are in the directory where the script is located, just preface the file name with ./.
user@rbiped:~/bash-scripts/ramblings# ./ello-wurld.sh  
Ello Wurld!
  • Supply the full location of the script, including all nested directories starting from root:
user@rbiped:~/bash-scripts/ramblings# /home/user/bash-scripts/ramblings/ello-wurld.sh  
Ello Wurld!
  • Once again from within the directory where the script is located, call the script using the bash command:
user@rbiped:~/bash-scripts/ramblings# bash ello-wurld.sh  
Ello Wurld!

When executed, the script runs invoking the echo command to print out our Ello Wurld! string to the console and immediately exits upon completion. Pretty simple stuff yeah? Not so fast!

After you run a script there is another portion of output that quietly passes itself to the Operating System in the background; the exit code!

Now run script again, only this time after it prints out your Ello Wurld! string enter the following command:

user@rbiped:~/bash-scripts/ramblings# echo $?  
0

If all proceeds as planned and everything executes inside of your script without error you should get a return code of 0. If all we are doing is using very basic commands like echo in our scripts, it is highly unlikely we will see any non-zero exit codes. It's when you start building logic and adding complexity with conditional statements that non-zero exit codes start to crop up and require handling.

For now we are focusing on the basics, so I am not going to traipse too horribly far into exit code usage, error handling, and the associated explanations.


The For Loop
#!/bin/bash

# Explain the output of the ls command being executed using the for-loop
/bin/echo “The following Home directories exist on this system: “

# Use the “ls” command to print a list of existing subdirectories and/or files under the /home directory
for item in $(ls /home);  
do  
    /bin/echo $item
done

Sample output:

User  
Cheryl  
Linda

The above script, as indicated by the included comments, does the following:

  1. Identifies the shell used to interpret the commands about to be passed to it.
  2. Uses the ls command to list all files and subdirectories under the "home" directory.
  3. Iterates over the output of the ls command using a for-loop, calling the echo command on each item.

The IF Statement

If statements in BASH scripts have the following basic structure:

if [[ test == this ]];  
then  
    $(do this)
else  
    $(do this)
fi
  • IF – Tests/compares a variable, command, or argument with an expected value.
  • THEN – Indicates what to do if the test from the “IF” portion passes or is evaluated true.
  • ELSE – Indicates what to do if the test from “IF” fails or is evaluated false.
  • FI – closes the if-statement

Remember the return codes that I mentioned earlier? If statements are a great way of adding logic to a script to interpret exit codes and validate whether commands in your script run as expected. I will add an if statement to our for-loop example above to illustrate…

#!/bin/bash
# Explain the output of the ls command being executed using the for-loop
/bin/echo “The following Home directories exist on this system: “

# Use the “ls” command to print a list of existing subdirectories and/or files under the /home directory
for item in $(ls /home);  
do  
    if [ $(ls -l /home | grep total | cut -d " " -f2) -eq 0 ];
    then
        /bin/echo “You don’t got nuffin’ in your HOME (pronounced “ohm”) directory Cap’n!”        
    else
        /bin/echo $item
    fi
done

As you remember from above, our for-loop goes through and prints the output of ls one item at a time.

With this example I kept the for-loop for iterating through the list of output from the ls command, but I added an IF statement to check if the directory is empty. If the total items in the directory evaluates to 0, instead of just exiting the script prints a warning message stating the directory is empty.

In order the newly formed script does the following:

  1. Identifies the shell used to interpret the commands about to be passed to it.
  2. Uses a for-loop to iterate over the output of the ls command.
  3. Uses an if-statement to check if the directory that the ls command is being used on actually has any sub-directories or files present.
  4. If there are contents in the directory, each item is printed to the console using the echo command.

The While Loop

The structure for the while loop is as follows:

while [ condition ];  
do  
    $(command)
done

Example script:

#!/bin/bash
test=1

while (( $test <= 11 ));  
do  
    /bin/echo $test
    test=$(( test+1 ))
done

The above example script does the following:

  1. Defines BASH as the shell to interpret our script's contents.
  2. Sets a single variable called "test" equal to the numeric value "1".
  3. Uses a while loop to evaluate the variable, checking if it is less than or equal to the number eleven.
  4. While "test" is less than or equal to eleven, the value of test is printed to the console using the echo command and incremented by one.
  5. When the value of "test" exceeds eleven the loop breaks and the script ends execution.

    *double parenthesis are used to evaluate numeric values


Conclusion

Mastering the syntax for constructing basic For-loops, If-statements, and While-loops will rocket you on your way to becoming a seasoned scripting guru. Once you feel you’ve mastered the use of these tools try incorporating other tools like awk, sed, cut, and the many variations of grep.

Stuck? Google is your friend! If you’re struggling with something chances are many other people have hit the same wall at some point. Look for answers. If you can’t find the answer you’re looking for ask for help! People in the open source community like to be bothered with these things. Some of us even ENJOY it!

Resources

RamblingBiped

Read more posts by this author.