Automation

BASH scripting: Basics

BASH scripting: Basics

DevOps and automation are now essential software development components as technology advances. Many developers are turning to BASH scripting language, the default shell on most Linux and macOS distributions, to automate laborious tasks and streamline development. This article will explore the advanced usage of the latest version of BASH scripting language in DevOps and automation.

This article will discuss the advanced usage of the newest version of BASH scripting language in DevOps and automation. BASH scripting language is a powerful tool used by DevOps professionals to automate and optimize workflows. Its latest version has many advanced features to help developers reduce errors, reduce time, and optimize their tasks.

What is BASH Scripting Language?

The BASH (Bourne Again SHell) scripting language is a command-line tool that DevOps professionals widely use for automation and system administration. It is a free and open-source language available on most Linux and Unix-based operating systems.

Why should I use BASH for automation in my DevOps life?

BASH is a popular choice for DevOps and automation for several reasons:

  • It is a versatile and flexible scripting language suitable for various tasks, from simple file operations to complex system administration.
  • It provides a powerful language to automate repetitive tasks, reduce errors, and optimize workflows.
  • It comes with an extensive library of commands and functions, allowing complex tasks to be completed quickly and easily.

BASH scripting language basic constructions

BASH scripting language has some basic constructions that are essential for writing scripts. These include variables, conditionals, loops, functions, and more. Knowing how to use these constructions correctly is key to writing effective scripts.

Variables and data types

In BASH, variables are used to store data and can be of different types, including integers, strings, and arrays. You can use variables to store values, manipulate them, and pass them as arguments to functions.

Let’s check some examples:

  1. Storing and manipulating integers:
# declare an integer variable
count=5

# add 1 to the count variable
((count++))

# print the value of the count variable
echo "Count is now $count"
  1. Storing and manipulating strings:
# declare a string variable
greeting="Hello, World!"

# concatenate the greeting variable with another string
greeting="$greeting How are you?"

# print the value of the greeting variable
echo $greeting

Variables can store different types of data, such as integers, strings, and arrays.

Conditional Statements:

Conditional statements are used to execute code based on certain conditions. In BASH, you can use if/then/else statements to test conditions and execute code accordingly. You can also use case statements to test multiple conditions.

Examples:

  1. Simples if-else statement:
# check if a file exists
if [ -f "example.txt" ]; then
    echo "File exists."
else
    echo "File does not exist."
fi

This code determines whether the file "example.txt" is present in the current directory. If it is, the script prints "File exists." If not, the script prints "File does not exist.”

  1. Case statement:
# prompt user for input
read -p "Enter a fruit: " fruit

# check user's input and act accordingly
case $fruit in
    "apple")
        echo "You chose an apple."
        ;;
    "banana")
        echo "You chose a banana."
        ;;
    "orange")
        echo "You chose an orange."
        ;;
    *)
        echo "You didn't choose a valid fruit."
        ;;
esac

This code prompts the user to enter a fruit and then uses a case statement to check which fruit was chosen. Depending on the input, a corresponding message is printed. If the input is not a recognized fruit, the script outputs "You didn't choose a valid fruit.”

Loops:

Loops are used to execute code repeatedly. In BASH, you can use for, while, and until loops to execute code based on certain conditions. You can also use break and continue statements to control the flow of the loop.

Examples to the rescue:

  1. For loop:
# iterate over a list of values and perform an action for each one
for fruit in apple banana orange; do
    echo "I like to eat $fruit."
done

This code uses a for loop to iterate over a list of fruits and print a message for each one. The loop assigns each value from the list (apple, banana, and orange) to the fruit variable, then executes the echo command with that value as an argument in the message.

  1. While loop:
# set an initial value for a counter
count=1

# use a while loop to repeat an action while a condition is true
while [ $count -le 5 ]; do
    echo "Count is $count."
    ((count++))
done

This code initializes a counter variable to 1 and then uses a while loop to print a message with the current count value while the count is <= 5. The loop increments the count value by 1 with each iteration.

  1. Until loop:
# repeatedly perform an action until a condition is true
count=1
until [ $count -gt 5 ]; do
    echo "Count is $count."
    ((count++))
done

This code uses an until loop to repeatedly print a message with the current count value until the count is greater than 5. The loop starts the count variable at 1 and checks if the count is greater than 5 at the beginning of each iteration. If it's not greater than 5, the loop executes the echo command with the current count value and adds 1 to it.

  1. Nested for loop:
# iterate over two lists of values and perform an action for each pair
fruits=("apple" "banana" "orange")
colors=("red" "yellow" "orange")

for i in "${!fruits[@]}"; do
    for j in "${!colors[@]}"; do
        if [ $i -eq $j ]; then
            echo "${fruits[$i]} is $colors[$j]."
        fi
    done
done

This code uses a nested for loop to iterate over two lists – fruits and colors – and print a message for each pair of values with the same index. The loop uses the ! operator to get the index of each value in the list, then checks if the indices are equal with an if statement. If they are, the loop executes the echo command with the corresponding fruit and color values substituted into the message.

Functions:

In BASH, functions are used to modularize and group code that performs a specific task. Calling functions allows you to easily execute the code with optional arguments for increased flexibility. Creating and using functions is easy and can be done with either the function keyword or the () syntax.

Let’s read some code in examples:

  1. Simple function:
# define a function that prints a message
greet() {
    echo "Hello, world!"
}

# call the function
greet

The greet function is defined in the code. When called, it prints "Hello, world!" to the console. To invoke it, simply use its name. Running the script will produce the expected output.

  1. Function with arguments:
# define a function that takes two arguments and performs an action
multiply() {
    result=$(( $1 * $2 ))
    echo "The product of $1 and $2 is $result."
}

# call the function with two arguments
multiply 3 5

The multiply function takes two arguments and multiplies them together. It then prints a message to the console, including the input values and the resulting product. When run, the script prints "The product of 3 and 5 is 15." to the console.

  1. Function with a return value:
# define a function that takes a number as input and returns its square
square() {
    result=$(( $1 * $1 ))
    return $result
}

# call the function and store the return value in a variable
num=4
square $num
result=$?

echo "The square of $num is $result."

The square function takes a number as an input, squares it, and returns the result. When called with the value of num, the outcome is stored in result. The script prints a message to the console, displaying the input value and the result. Running the script prints "The square of 4 is 16." to the console.

Arrays:

Arrays are a powerful data structure in BASH, used to store multiple values in a single variable. Several mechanisms are provided to work with them, such as the declare keyword and the [] syntax. Knowing how to use arrays is essential for creating robust and efficient scripts, as they can be used to store and manipulate large amounts of data. This includes accessing individual elements, looping over the array, and performing operations on the entire array.

Here are some examples:

  1. Indexed array
# define an array of colors and loop over each item
colors=("red" "green" "blue")

for color in "${colors[@]}"; do
    echo "I like the color $color."
done

The colors array is defined with three items: red, green, and blue. The for loop iterates over each item and prints a message with the current item's value. When the script is executed, it will display "I like the color red.", "I like the color green.", and "I like the color blue." in the console.

  1. Associative array:
# define an associative array of countries and their capital cities
declare -A capitals
capitals["United States"]="Washington, D.C."
capitals["France"]="Paris"
capitals["Japan"]="Tokyo"

# loop over the keys in the array and print the corresponding values
for country in "${!capitals[@]}"; do
    capital="${capitals[$country]}"
    echo "The capital of $country is $capital."
done

The capitals associative array maps countries to their capital cities, created with the declare -A command. Three countries are set as values: United States, France, and Japan. The for loop iterates over the keys (${!capitals[@]}), gets their corresponding values, and prints a message with the country and capital substituted. When the script is run, it will output "The capital of United States is Washington, D.C.", "The capital of France is Paris.", and "The capital of Japan is Tokyo." to the console.

  1. List
# define a list of programming languages and print them as a comma-separated string
languages=("Python" "JavaScript" "Ruby" "Java" "C++")
list=$(IFS=, ; echo "${languages[*]}")
echo "My favorite programming languages are: $list."

This code creates an array containing a list of five programming languages. It uses the IFS variable to set the field separator to a comma, and the echo command with the "${languages[*]}" expression to join the array items into a comma-separated string, which is stored in the list variable. When the script is run, it prints "My favorite programming languages are: Python, JavaScript, Ruby, Java, C++." to the console.

Debugging BASH Scripts

Debugging is an essential part of software development, and BASH provides several mechanisms for debugging scripts. These include setting the set -x option, using the echo command to print variables and output, and using the trap command to handle signals.

Let's examine some examples of how to use it:

  1. Using set -x to print debugging information:
#!/bin/bash

set -x

# define a function that adds two numbers
add() {
    result=$(( $1 + $2 ))
    echo "The sum of $1 and $2 is $result."
}

# call the function with two arguments
add 3 5

This code defines a function that adds two numbers and prints the result. The set -x command is used to enable debugging output. When the script runs, the shell will print each command and its arguments before executing, so you can observe the script's execution. In this case, it will look something like:

+ add 3 5
+ result=8
+ echo 'The sum of 3 and 5 is 8.'
The sum of 3 and 5 is 8.

The add function was called with the arguments 3 and 5, yielding 8 as the sum.

  1. Using trap to handle errors:
#!/bin/bash

# define a function that will cause an error
fail() {
    echo "Something went wrong!" >&2
    exit 1
}

# set a trap to call the fail function on error
trap fail ERR

# do some operations that might cause an error
mkdir /root/test
rm /root/test

The fail function is defined, which prints an error message and exits with an error code. A trap is set to call the fail function when an error occurs (using the ERR signal). The script then attempts to create a directory in the root directory, which will fail due to lack of permissions, and then deletes the directory, which will succeed. If the mkdir command fails, the fail function will be called, and the script will exit with an error code of 1. The error message will be printed to the standard error stream (>&2 redirection in fail).

Benefits of Utilizing BASH for DevOps and Automation

BASH offers many advantages when it comes to DevOps and automation:

  • Increased speed and efficiency: scripting is speedy and efficient.
  • Unrivaled flexibility and power: it can be used to accomplish a wide range of tasks.
  • Open-source: available on the majority of Linux and Unix-based operating systems.
  • Vast library of commands and functions: difficult tasks can be made easy.

Summary

This article aimed to give you a basic understanding of what BASH can do for you. It's a powerful tool that can help you automate tasks, customize your environment, and write powerful scripts. I'll provide tips and tricks for BASH in future articles, and explain each statement in detail.

For example, we'll show you how to set up aliases, create functions, and work with command-line arguments. You'll also learn debugging techniques, setting environment variables, and more. Don't miss out – join our newsletter to stay up to date with all the great content!

A blog for self-taught engineers

Сommunity is filled with like-minded individuals who are passionate about learning and growing as engineers.