Linux Basics #8 - Bash Scripting

Last Edited: 1/12/2025

This blog post introduces basics of bash scripting.

DevOps

So far, we have been covering various commands in bash, which we have been typing and running individually. However, we might want to combine these commands with logic to automate processes. In this article, we will cover bash scripting, which allows us to do exactly that.

Creating Shell Script

Bash scripting can be done by creating a shell script file, which conventionally has a .sh file extension. We can create this file using touch test.sh or vim test.sh with Vim. In the shell script, we need to specify the shell binary to execute the commands in the file by writing a shebang #! followed by the path to the binary. As a test, try replicating the example below:

test.sh
#! /bin/bash
 
echo "Hello World!"

The shell script can be executed using bash test.sh or ./test.sh. (You will need to change the permission of test.sh to allow the user to execute it using chmod. If you are unsure about permissions, I recommend checking out Linux Basics #6 - Permissions.) You should see the output Hello World! printed on the shell.

Variables & Arguments

In the shell script, you can define variables in capital letters and refer to them with the $ sign. For example, you can set OUTPUT_DIR="/root" and print it out using echo "OUTPUT_DIR: $OUTPUT_DIR". You can also accept arguments from the user, such as ./test.sh arg_1 arg_2, which you can refer to in the script using $<arg_number>.

test.sh
#! /bin/bash
 
OUTPUT_DIR="/root"
echo "OUTPUT_DIR $OUTPUT_DIR"
echo "ARGUMENTS $1, $2"

The above example demonstrates how variables and arguments work in shell scripts. You can replicate it and run it with ./test.sh arg_1 arg_2 using arbitrary arguments and check the output.

Logic

In addition to running multiple commands and using variables and arguments, you can implement logic for running commands using for loops, while loops, and if statements. You can set up a for loop as follows:

for i in {1..10}
do
     touch "$OUTPUT_DIR/$i.txt"
done

The while loop is useful for obtaining user input, which can be achieved by combining it with the read command and a case statement. The command read -p "<prompt>" <variable> can display a prompt and store the user input in the variable. Depending on the validity of the user input, we can continue prompting the user with the while loop.

while true; do
     read -p "Would you like to continue?" yn
     case $yn in
          [Yy]*) break;;
          [Nn]*) exit;;
          *) echo "Please answer in Y[y] or N[n]";;
     esac
done

The above example demonstrates how to ask the user to continue the process or not. It uses a case statement and regular expressions to decide whether to break out of the loop with break, exit the process with exit, or continue asking for user input. If statements are helpful for checking arguments, as shown below:

if [ $1 -lt 2 ]; then
     echo "The argument cannot be less than 2."
     exit
else
     echo "Creating $1 number of .txt files in $OUTPUT_DIR"
fi

By combining the above statements, you can create a script where you specify the number of text files to create as a argument and ask the user to confirm execution as follows:

# Argument validation
if [ $1 -lt 2 ]; then
     echo "The argument cannot be less than 2."
     exit
else
     echo "Creating $1 number of .txt files in $OUTPUT_DIR"
fi
 
# User validation
while true; do
     read -p "Would you like to continue?" yn
     case $yn in
          [Yy]*) break;;
          [Nn]*) exit;;
          *) echo "Please answer in Y[y] or N[n]";;
     esac
done
 
# File creation
for i in $(seq $1)
do
     touch "$OUTPUT_DIR/$i.txt"
done

The above example uses the seq (sequence) command to create a sequence of numbers from the argument. You can replicate the above script and run it to confirm that the text files are created successfully. As a challenge, you can write another script to delete all the created files.

Conclusion

In this article, we covered the basics of bash scripting, which allows us to automate running multiple commands with logic. There are many other useful syntaxes, such as putting slow processes in the background with &. If you're interested, I recommend researching more. (You might be surprised to see function names overlapping with those in C, as bash is written in C.)

Resources