Efficient Coding with Bash Scripts: An In-Depth Tutorial

Utsav Desai
19 min readFeb 16, 2023

--

What is Bash Scripting?

Bash scripting is a way to automate tasks on a Unix or Linux system using the Bash shell, which is a command-line interface that allows users to interact with the operating system by executing commands.

A Bash script is a series of commands that are stored in a file and can be executed as a program. Bash scripts can be used to automate repetitive tasks, such as running backups, system maintenance, or deploying applications.

Bash scripts can contain a combination of commands, control structures (such as loops and conditionals), and variables, which allow users to create more complex and flexible scripts. Bash scripts can also accept command-line arguments, allowing users to customize their behavior.

Bash is one of the most widely used shells on Unix and Linux systems, so learning Bash scripting can be useful for system administrators, developers, and anyone who needs to automate tasks on these systems.

Frist Bash Script

here’s an example of a simple Bash script that prints “Hello, world!” to the terminal:

#!/bin/bash
echo "Hello, world!"

Here’s how it works:

  1. The first line #!/bin/bash is called a shebang and tells the system that this file should be executed using the Bash shell.
  2. The second line uses the echo command to print "Hello, world!" to the terminal.

To run this script, you can save it to a file (e.g. hello.sh), make it executable with the chmod command (chmod +x hello.sh), and then run it using ./hello.sh. This should output "Hello, world!" to the terminal.

Note that in order to run this script, you need to have Bash installed on your system. Most Unix and Linux systems come with Bash pre-installed, but if you’re using a different operating system, you may need to install it first.

Variable

In Bash scripting, a variable is a named value that can be assigned a value, and that value can be referenced and manipulated throughout the script. Bash variables can be used to store data, perform calculations, and pass information between commands and functions.

In Bash, variables are typically defined using the syntax name=value, where name is the name of the variable and value is the value that it should be assigned. For example:

myvar="Hello, world!"

This creates a variable called myvar and assigns it the value "Hello, world!". To reference the value of a variable, you can simply use the $ symbol followed by the name of the variable. For example:

echo $myvar

This will output the value of the myvar variable to the terminal.

In Bash, variables can also be used in more complex expressions and operations. For example, you can perform arithmetic operations on variables like this:

x=5
y=10
z=$((x + y))

This creates two variables, x and y, with the values 5 and 10, and then creates a third variable, z, that stores the result of the addition of x and y.

Bash variables can also be passed as arguments to functions and scripts, allowing data to be shared and manipulated across different parts of the script.

It’s important to note that Bash variable names are case-sensitive and can include letters, numbers, and underscores, but cannot begin with a number. It’s also a good practice to use descriptive names for your variables to make your code easier to read and understand.

Command Line Arguments

Command line arguments are a way to pass input values to a Bash script when it is executed. These arguments are passed as strings and can be used by the script to modify its behavior or perform different actions based on the input.

In Bash, command line arguments are accessed using special variables called positional parameters. The first argument is referred to as $1, the second as $2, and so on. The $0 variable contains the name of the script itself.

Here’s an example of a Bash script that uses command-line arguments:

#!/bin/bash

echo "Hello, $1!"

In this script, the $1 variable is used to print a personalized greeting to the user. If the script is executed with the command ./hello.sh John, it will output "Hello, John!" to the terminal.

Bash scripts can also use other variables and expressions in combination with command line arguments to perform more complex operations. For example, you might use a for loop to process multiple command line arguments:

#!/bin/bash

for arg in "$@"
do
echo "Processing argument: $arg"
done

In this script, the $@ variable is used to iterate over all of the command line arguments and print a message for each one. If the script is executed with the command ./process.sh apple orange banana, it will output:

Processing argument: apple
Processing argument: orange
Processing argument: banana

Using command line arguments in Bash scripts can make your code more flexible and customizable, allowing users to provide input data and modify the behavior of your scripts.

System Variable

In Bash scripting, there are several system variables that are predefined and can be used to access information about the current environment, user, and system. These system variables can be very useful in writing Bash scripts that automate tasks and perform system administration tasks.

Here are some of the most commonly used system variables in Bash scripting:

  1. $HOME - The path to the current user's home directory.
  2. $USER - The name of the current user.
  3. $PWD - The current working directory.
  4. $HOSTNAME - The name of the current host.
  5. $PATH - The list of directories that the shell searches for executables.
  6. $SHELL - The path to the current user's shell.
  7. $PS1 - The primary prompt string for the shell.
  8. $PS2 - The secondary prompt string for the shell.
  9. $OSTYPE - The type of operating system that the shell is running on.
  10. $LINENO - The current line number in the script.
  11. $0: This variable contains the name of the script or shell being executed.
  12. $1-$9: These variables contain the first nine command line arguments passed to the script. $1 contains the first argument, $2 contains the second argument, and so on. If there are more than nine arguments, you can access them using the $10, $11, and so on.
  13. $#: This variable contains the number of command line arguments passed to the script.
  14. $@: This variable contains all of the command line arguments passed to the script, separated by spaces. You can use this variable to iterate over all of the arguments using a loop or perform other operations.
  15. $?: This variable contains the exit status of the last executed command or script. An exit status of 0 indicates success, while any other value indicates an error or failure.
  16. $$: This variable contains the process ID (PID) of the currently running script or shell.
  17. $SECONDS: This variable contains the number of seconds that the script has been running. This can be useful for measuring the execution time of your scripts or for implementing time-based logic.
  18. $RANDOM: This variable contains a random integer between 0 and 32767. You can use this variable to generate random numbers for your scripts or to implement random behavior.

Quotes

Quotes are an important concept in Bash scripting as they are used to control how the shell interprets arguments and variables. In Bash, there are three types of quotes that can be used:

1. Single quotes ('): When a string is enclosed in single quotes, the shell treats it as a literal string, with no special characters or variables interpreted. For example:

echo 'Hello $USER'  # Output: Hello $USER

In this example, the $USER variable is not interpreted because it is enclosed in single quotes.

2. Double quotes ("): When a string is enclosed in double quotes, the shell interprets variables and some special characters within the string. For example:

echo "Hello $USER"  # Output: Hello <your username>

In this example, the $USER variable is interpreted and replaced with the current username.

Double quotes can also be used to preserve whitespace within a string. For example:

echo "This     string  contains  multiple      spaces."  # Output: This     string  contains  multiple      spaces.

In this example, the multiple spaces within the string are preserved.

3. Backticks (`): Backticks are used to execute a command and return the output as a string. For example:

echo "The current date is: `date`"  # Output: The current date is: <current date and time>

In this example, the date command is executed and its output is returned as a string, which is then included in the larger string.

It’s also worth noting that within double quotes, some special characters, such as $, !, and \, can still be interpreted by the shell. To prevent this, you can use a backslash (\) to escape the character. For example:

echo "The \$USER variable is: $USER"  # Output: The $USER variable is: <your username>

In this example, the $ character is escaped with a backslash to prevent it from being interpreted as a variable.

Command Substitution

Command substitution is a feature in Bash scripting that allows the output of a command to be substituted as a value within another command or expression. Command substitution is denoted by enclosing a command within $( and ). There are two ways to perform command substitution in Bash:

1. Using $() syntax: This is the recommended way to perform command substitution in Bash. For example:

echo "The current working directory is: $(pwd)"

In this example, the pwd command is executed and its output is substituted as the argument to echo.

2. Using backticks: Backticks can also be used to perform command substitution, but it is less recommended as it can lead to parsing errors if the command contains backticks or other special characters. For example:

echo "The current working directory is: `pwd`"

This example is equivalent to the previous example, but uses backticks instead of $() syntax.

Command substitution can be used to simplify complex expressions or to pass the output of one command as an argument to another command. For example, you can use command substitution to count the number of files in a directory:

echo "There are $(ls | wc -l) files in this directory"

In this example, the ls command is executed to list the files in the current directory, and the output is piped to the wc -l command to count the number of lines (which is equal to the number of files). The resulting count is then substituted as the argument to echo.

Overall, command substitution is a useful feature in Bash that can help to simplify complex commands and expressions, and make your scripts more efficient and readable.

Exporting variable

In Bash scripting, variables are by default only available within the current shell session or script. If you want to make a variable available to other processes or sub-shells, you can use the export command.

The export command allows you to mark a variable for automatic export to the environment of subsequently executed commands. When a variable is exported, its value is copied to the environment of child processes and sub-shells. The general syntax for exporting a variable is as follows:

export VARIABLE_NAME=value

For example, to export a variable named MY_VAR with the value hello world, you would use the following command:

export MY_VAR="hello world"

Once the variable is exported, you can access its value from any subsequently executed command or script. For example, if you execute the following script:

#!/bin/bash

export MY_VAR="hello world"

./other_script.sh

And other_script.sh contains the following line:

echo "The value of MY_VAR is: $MY_VAR"

Then the output of other_script.sh will be:

The value of MY_VAR is: hello world

Note that when you export a variable, it will be visible to all child processes and sub-shells, but not to the parent process or parent shell. To make the variable available to the parent process or shell, you can use the source command to execute the script in the current shell session:

source myscript.sh

Or use the dot operator (.) which is an alias for the source command:

. myscript.sh

Overall, exporting variables can be a useful way to share data between different processes or sub-shells, and can help to simplify complex scripts and make them more modular.

Environment Variable or exporting variable permanently

In Bash scripting, you can make a variable available to all processes and sessions by setting it as an environment variable. Environment variables are variables that are set in the shell environment and are available to all processes that are executed from the shell. They can be used to configure system-wide settings, set default paths, or define global variables that can be accessed by all users and processes.

To set an environment variable in Bash, you can use the export command followed by the variable name and value:

export VARIABLE_NAME=value

For example, to set an environment variable named MY_VAR with the value hello world, you would use the following command:

export MY_VAR="hello world"

However, this command only sets the variable for the current session. To make the variable permanent, you need to add it to your shell’s configuration file, which is typically located at ~/.bashrc or ~/.bash_profile.

To set an environment variable permanently, add the export command to the end of the configuration file:

echo 'export MY_VAR="hello world"' >> ~/.bashrc

This will append the export command to the end of the .bashrc file, which will be executed every time you start a new Bash session. Alternatively, you can open the .bashrc file in a text editor and add the export command manually.

Once you have added the environment variable to the configuration file and restarted your terminal or opened a new shell session, the variable will be available to all processes and scripts that are executed from that session. You can access the variable in your scripts using the $VARIABLE_NAME syntax.

Overall, using environment variables can be a powerful way to configure your system and make global settings available to all processes and users. However, it is important to be careful when modifying system-wide settings, as they can have unintended consequences and may affect the behavior of other programs and users.

User Input

In Bash scripting, you can prompt the user to enter input using the read command. The read command reads a line of input from the user and assigns it to a variable.

The basic syntax for read command is as follows:

read VARIABLE_NAME

For example, to prompt the user to enter their name and store it in a variable called name, you would use the following code:

#!/bin/bash

echo "What is your name?"
read name

echo "Hello, $name!"

When this script is executed, it will display the message “What is your name?” and wait for the user to enter their name. Once the user has entered their name and pressed Enter, the script will print a greeting using the entered name.

You can also prompt the user to enter multiple values and store them in separate variables by specifying the variable names as arguments to the read command. For example, the following code prompts the user to enter their name and age, and stores the values in the name and age variables:

#!/bin/bash

echo "What is your name?"
read name

echo "What is your age?"
read age

echo "Hello, $name! You are $age years old."

The read command can also be used with the -p option to display a prompt message on the same line as the input. For example, the following code prompts the user to enter their name using a single read command with the -p option:

#!/bin/bash

read -p "What is your name? " name

echo "Hello, $name!"

In addition, you can use the -s option with the read command to read input without echoing it to the screen. This can be useful for reading passwords or other sensitive information. For example, the following code prompts the user to enter a password and stores it in a variable called password:

#!/bin/bash

read -s -p "Enter your password: " password

echo "Your password is: $password"

Overall, the read command is a simple and versatile way to prompt the user for input in Bash scripts, and can be used to create interactive command-line tools and applications.

If Statement

In Bash scripting, the if statement is used to conditionally execute code based on a specified condition. The basic syntax for the if statement is as follows:

if CONDITION; then
# code to be executed if condition is true
fi

The if statement evaluates the specified CONDITION, and if it is true, the code inside the then block is executed. If the CONDITION is false, the code inside the then block is skipped.

The CONDITION can be any command or expression that returns a status code of 0 for success (true) or non-zero for failure (false). For example, you can use comparison operators to compare two values or test if a file or directory exists:

if [ "$var1" -eq "$var2" ]; then
# code to be executed if var1 equals var2
fi

if [ -e "/path/to/file" ]; then
# code to be executed if file exists
fi

You can also use logical operators such as && (and) and || (or) to combine multiple conditions:

if [ "$var" -gt 0 ] && [ "$var" -lt 10 ]; then
# code to be executed if var is between 0 and 10
fi

if [ -d "/path/to/dir" ] || [ -f "/path/to/file" ]; then
# code to be executed if dir exists or file exists
fi

In addition, the if statement can be combined with the elif (else if) and else statements to handle multiple conditions:

if [ "$var" -eq 0 ]; then
# code to be executed if var equals 0
elif [ "$var" -gt 0 ]; then
# code to be executed if var is greater than 0
else
# code to be executed if var is less than 0
fi

Overall, the if statement is a fundamental tool for creating conditional logic in Bash scripts, and can be used to create powerful and flexible control flow in your code.

If Else Statement

In Bash scripting, the if-else statement is used to conditionally execute code based on a specified condition, and to execute an alternate code block if the condition is false. The basic syntax for the if-else statement is as follows:

if CONDITION; then
# code to be executed if condition is true
else
# code to be executed if condition is false
fi

The if-else statement evaluates the specified CONDITION, and if it is true, the code inside the then block is executed. If the CONDITION is false, the code inside the else block is executed.

The CONDITION can be any command or expression that returns a status code of 0 for success (true) or non-zero for failure (false). For example, you can use comparison operators to compare two values or test if a file or directory exists:

if [ "$var1" -eq "$var2" ]; then
# code to be executed if var1 equals var2
else
# code to be executed if var1 does not equal var2
fi

if [ -e "/path/to/file" ]; then
# code to be executed if file exists
else
# code to be executed if file does not exist
fi

You can also use logical operators such as && (and) and || (or) to combine multiple conditions:

if [ "$var" -gt 0 ] && [ "$var" -lt 10 ]; then
# code to be executed if var is between 0 and 10
else
# code to be executed if var is not between 0 and 10
fi

if [ -d "/path/to/dir" ] || [ -f "/path/to/file" ]; then
# code to be executed if dir exists or file exists
else
# code to be executed if dir does not exist and file does not exist
fi

Overall, the if-else statement is a fundamental tool for creating conditional logic in Bash scripts, and can be used to create powerful and flexible control flow in your code.

Test Condition

In the if statement, the square brackets ([]) are used to test a condition or expression. The square brackets are actually an alias for the test command, which evaluates the condition and returns a status code of 0 (true) or non-zero (false).

The if statement checks the exit status of the test command to determine whether the condition is true or false. The syntax for using the test command is:

[ CONDITION ]

For example, the following if statement tests if the variable $var is equal to the string "hello":

if [ "$var" = "hello" ]; then
echo "The variable is equal to hello."
fi

The expression inside the square brackets evaluates to true if $var is equal to "hello", and the code inside the if block is executed. If the expression is false, the code inside the if block is skipped.

For Loop

In Bash scripting, the for loop is used to iterate over a set of values and perform a set of actions for each value. The basic syntax for the for loop is as follows:

for VAR in VALUE1 VALUE2 ... VALUEN; do
# code to be executed for each value
done

In this syntax, VAR is a variable that is used to store each value from the list of values. The values are specified after the in keyword, separated by spaces.

Here’s an example of using the for loop to iterate over a list of values and print each value:

#!/bin/bash

for COLOR in red green blue; do
echo $COLOR
done

This script will output the following:

red
green
blue

You can also use variables in the list of values, and use the seq command to generate a sequence of numbers. For example:

#!/bin/bash

for i in {1..5}; do
echo "Number: $i"
done

for i in $(seq 1 5); do
echo "Number: $i"
done

Both of these loops will output the same result:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

The for loop is a powerful tool for iterating over lists of values and performing repetitive tasks. You can use it to perform a wide variety of tasks, from processing files and directories to managing data and resources.

While Loop

In Bash scripting, the while loop is used to execute a set of commands repeatedly as long as a certain condition is true. The basic syntax of a while loop is as follows:

while [ CONDITION ]; do
# code to be executed while CONDITION is true
done

In this syntax, CONDITION is a test that is evaluated before each iteration of the loop. If the test evaluates to true, the loop executes the code inside the do and done statements, and then re-evaluates the CONDITION test. If the test is still true, the loop continues to execute, otherwise, it exits.

Here’s an example of using a while loop to iterate over a list of numbers and print each one:

#!/bin/bash

i=1
while [ $i -le 5 ]; do
echo "Number: $i"
i=$((i+1))
done

This script will output the following:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

In this example, the CONDITION test is [ $i -le 5 ], which checks if the value of $i is less than or equal to 5. The loop continues to execute as long as this test evaluates to true. The code inside the loop prints the value of $i and then increments it by 1 using the expression i=$((i+1)).

The while loop is useful when you want to execute a set of commands repeatedly as long as a certain condition is true. You can use it to process data, read input, and manage resources in your Bash scripts.

Real-Time Example

One of the most important real-time examples of Bash scripting is automating system administration tasks. Bash scripts can be used to automate a wide variety of tasks that are typically performed by system administrators, such as system maintenance, backups, and software updates.

Here’s an example of a Bash script that automates the process of backing up a directory:

#!/bin/bash

# Directory to backup
dir="/home/user/Documents"

# Backup destination directory
backup_dir="/mnt/backup"

# Backup file name
backup_file="backup_$(date +%Y-%m-%d_%H-%M-%S).tar.gz"

# Create backup directory if it does not exist
if [ ! -d "$backup_dir" ]; then
mkdir "$backup_dir"
fi

# Create backup file
tar -czf "$backup_dir/$backup_file" "$dir"

# Delete backup files older than 30 days
find "$backup_dir" -type f -name "backup_*.tar.gz" -mtime +30 -delete

echo "Backup created: $backup_dir/$backup_file"

In this script, the dir variable specifies the directory to be backed up, while the backup_dir variable specifies the location where the backup should be saved. The backup_file variable is used to generate a filename for the backup that includes the current date and time.

The script first checks if the backup directory exists, and creates it if it does not. It then creates the backup file using the tar command and deletes any backup files that are older than 30 days using the find command.

By scheduling this script to run periodically using a tool like cron, you can automate the process of backing up your files and ensure that your data is safe and secure.

This is just one example of how Bash scripting can be used in real-time scenarios to automate system administration tasks. By combining Bash with other tools and technologies, you can create powerful scripts that can save time and improve efficiency in your work.

How to set up SSH Keys Using bash scripting

SSH keys are a secure and convenient way to authenticate and connect to remote servers without having to enter a password each time. You can set up SSH keys in Bash scripting by following these steps:

1. Check for existing SSH keys: Before generating new SSH keys, it’s a good idea to check if you already have existing SSH keys. You can check for existing keys by running the following command in your terminal:

ls ~/.ssh/id_*

If you see any files listed, you already have SSH keys.

2. Generate new SSH keys: If you don’t have SSH keys, you can generate new ones by running the following command in your terminal:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

This command will generate a new SSH key pair, consisting of a private key and a public key. The private key will be saved to ~/.ssh/id_rsa, and the public key will be saved to ~/.ssh/id_rsa.pub.

3. Add your public key to the remote server: To connect to a remote server using SSH keys, you need to add your public key to the remote server’s authorized_keys file. You can do this by copying your public key to the remote server using the ssh-copy-id command:

ssh-copy-id user@remote_server

This command will copy your public key to the remote server and add it to the authorized_keys file.

4. Test your SSH connection: Once you have set up your SSH keys, you can test your connection to the remote server by running the following command in your terminal:

ssh user@remote_server

This command will connect you to the remote server using your SSH keys, and you should not be prompted for a password.

You can use these steps in Bash scripting to automate the process of setting up SSH keys for multiple servers or users. By creating a Bash script that generates and copies SSH keys, you can save time and improve the security of your remote connections.

--

--

Utsav Desai

Utsav Desai is a technology enthusiast with an interest in DevOps, App Development, and Web Development.