Introduction to Bash Scripting – Part II

In the Introduction to Bash Scripting guide that I published previously we reviewed the foundations of bash scripting. At this point, you should have a basic idea of how to declare variables, run commands inside a script and have a general understanding of the basic fundamentals. If you don’t have a basic understanding of these concepts I highly encourage you to revisit the post and give it a read. Now, let’s dive into this article’s topics, or as one of my favorite YouTubers would say:

FUNCTIONS

The power of the scripts lies in the ability to automate actions via the use of functions. According to MathInside, a function is “a relation from a set of inputs to a set of possible outputs where each input is related to exactly one output.” Or in simpler words, you can achieve anything you want from creating a file or folder, to even restarting the system.

There are predefined functions in Bash that govern logic conditionals and loops. These are used to compare variables, react based upon an input or create loops. I will cover these first to then explain how to create a custom function.

SIMPLE IF STATEMENTS

An IF statement is a conditional function that completes a task based on the validation of a condition, meaning:

  • If this is true, then do that
  • If this is not true, then do this other thing

In Bash this If Statement is declared first by calling the function and indicating the conditional. Let’s say that since my name is Isaac, I want to validate that the user writes my name in the script. To accomplish this I would use:

  • if [ “$NAME” == “Isaac” ]
    • With this conditional, we are expecting the variable $NAME to be equal to the string Isaac
  • When this condition is met, then you proceed with the code you want to execute
  • Finish by closing the conditional by writing fi

#! /bin/bash

read -p “Enter your name: ” NAME

if [ “$NAME” == “Isaac” ]
then
echo “Hi Isaac”
fi

IF-ELSE

Else is the definition of what actions will happen if the condition is not met. By default, this is null and can be updated to suit your needs.

Based on the previous example we can say something like “You’re not authorized!” and end the function. This function will then go as follows:

if [ “$NAME” == “Isaac” ]
then
echo “Hi Isaac”
else
echo “You’re NOT Authorized!”
fi

ELSE-IF (elif) STATEMENT

You will use if-else when you need to validate more than one condition. Let’s say that you want to authorize only Isaac and Angel to access the script, and if the user does not input either of these names we will call it out as follows:

if [ “$NAME” == “Isaac” ]
then
echo “Your name is Isaac”
elif [ “$NAME” == “Angel” ]
then
echo “Your name is Angel”
else
echo “Your name is NOT Isaac or Angel”
fi

COMPARISON

Let’s say that you need to compare two numerical values, like the ages of two individuals. For this example, you would like to compare which is greater and print out the result in the console.

You can complete this by using the conditionals such as greater than (-gt). I’ve added a cheatsheet as comments below 😉

NUM1=31
NUM2=5
if [ “$NUM1” -gt “$NUM2” ]
then
echo “$NUM1 is greater than $NUM2”
else
echo “$NUM1 is less than $NUM2”
fi

########
# 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 val1 is greater than val2
# val1 -ge val2 Returns true if val1 is greater than or equal to val2
# val1 -lt val2 Returns true if val1 is less than val2
# val1 -le val2 Returns true if val1 is less than or equal to val2
########

FILE CONDITIONS

Much as in the comparisons above, you can validate the conditions of a File in the server. You can validate if a file exists, if it has certain permissions, etc. I’ve also added a mini cheatsheet to the end of the script 😉

FILE=”test.txt”
if [ -e “$FILE” ]
then
echo “$FILE exists”
else
echo “$FILE does NOT exist”
fi

########
# -d file True if the file is a directory
# -e file True if the file exists (note that this is not particularly portable, thus -f is generally used)
# -f file True if the provided string is a file
# -g file True if the group id is set on a file
# -r file True if the file is readable
# -s file True if the file has a non-zero size
# -u True if the user id is set on a file
# -w True if the file is writable
# -x True if the file is an executable
########

CASE STATEMENT

The case statements enable you to run some code based on the response of the user that is running the script. You will see that these case statements are used when configuring the properties of an application during its setup, and when agreeing with terms and conditions.

The following script is an easy to follow example of the logic of case statements where based on the user’s answer I let him know if he can have a beer with me or not:

# Note that the letters in format [xX] refer to input being case insensitive

read -p “Are you 21 or over? Y/N ” ANSWER
case “$ANSWER” in
[yY] | [yY][eE][sS])
echo “Great! Let’s have a Beer on me :)”
;;
[nN] | [nN][oO])
echo “Sorry, no underage drinking here ><“
;;
*)
echo “Please enter y/yes or n/no”
;;
esac

SIMPLE FOR LOOP

The for loops are cycles of a specific code that will repeat constantly based on the limits set by the developer. Let’s say that you have a string of four (4) names and would like to greet each of these names. You would want to do something like:

# NAMES is a String of names

NAMES=”Isaac Kevin Laura John”
# NAME is a variable for each name in $NAMES string
for NAME in $NAMES
do
echo “Hello $NAME”
done

FOR LOOP TO RENAME FILES

One great example of the use of for loops is the use of these cycles to automate the renaming in bulk of files. You could achieve this by using the following example code:

FILES=$(ls *.txt)
NEW=”new”
for FILE in $FILES
do
echo “Renaming $FILE to new-$FILE”
mv $FILE $NEW-$FILE
done

WHILE LOOP – READ THROUGH A FILE LINE BY LINE

What differences a While from a for loop is that the While, as its name states, as long as the condition is true it will continue to cycle in. Let’s say that you’re monitoring a log file that is being actively written by an application. You could use the while loop

LOG_PATH=”/path/to/log/file”
while IFS= read -r line
do
echo “$line”
done < “$LOG_PATH”

Where:

  • The syntax is as follows for bash:
    • while read -r line; do COMMAND; done < input.file
  • The -r option passed to read command prevents backslash escapes from being interpreted.
  • Add IFS= option before read command to prevent leading/trailing whitespace from being trimmed

CONCLUSION

These functions are very powerful. They enable you to achieve virtually anything you want as long as you can code it, and the best part is that if you run into an issue the likelihood of finding your answer online is pretty high.

I hope you’ve found this article to be helpful. I will cover the custom functions that you can create, along with some examples, on tomorrow’s post. Subscribe to my newsletter to receive a notification when I post new content! And remember to share these posts with your friends and family, or whoever you believe that this would be beneficial. See you in my next post!

Subscribe to my Newsletter

Exclusive offers, Industry insights and more!

Join 2,031 other subscribers