DEV Community

Quynh Nguyen
Quynh Nguyen

Posted on

Linux basics - Begin bash scripting

Bash (Bourne Again Shell) is a powerful Unix shell and command language interpreter, serving as the default shell for most Linux distributions and macOS. It provides a command-line interface for interacting with the operating system, executing commands, and automating tasks through shell scripts. Bash supports variables, control structures, functions, and command substitution, making it versatile for system administration, DevOps tasks, and general-purpose scripting. Its ability to pipe commands, redirect input/output, and utilize a vast array of built-in commands and utilities makes it an essential tool for developers and system administrators in managing and automating workflows in Unix-like environments.

According to DevOps roadmap, Bash is a must have skill for everyone who wants to jump into DevOps area. So I've researched and used it. In this article, I'll list down things that I use the most and keep them as my short notes. Hope they'll help you, too.

Strings and comments

In Bash, most elements, such as variables, command names, and function names, are treated as strings by default unless used in a specific context (e.g., arithmetic or file descriptors). If a string contains spaces or special characters, it must be enclosed in single or double quotes to ensure it is treated as a single entity. Single quotes preserve the literal value of the string, while double quotes allow for variable expansion and command substitution. If a string does not contain spaces or special characters, it can be used without quotes. Here are examples.

Hello
'Hello World!'
"I'm learning Bash."
Enter fullscreen mode Exit fullscreen mode

To print or display them in the terminal, use echo command.

echo Hello

NAME='Quynh Nguyen'

echo "Hello! My name is $NAME."

echo "It's nice to meet you."

echo 'Nice to meet you, too.'
Enter fullscreen mode Exit fullscreen mode

A comment starts with # symbol, and is ignored by the interpreter.

# This is just a comment, it does nothing else.
Enter fullscreen mode Exit fullscreen mode

Variables

A variable is a named storage that holds a value, typically a string, in a Bash program. Its value can be changed at any point during the execution of the program. A variable name can contain alphanumeric characters (letters and digits) and underscores (_), but it must begin with a letter or an underscore. It cannot start with a digit or contain spaces or special characters.

SUBJECT="Bash Scripting"

export CHAPTER="Variables"
Enter fullscreen mode Exit fullscreen mode

Without export keyword, a variable is local to the current shell session and is not accessible to child processes or sub shell sessions. While using export allows it to be inherited by all child processes or sub shell sessions.

Although we can name variables with lowercase, it's a common convention in Bash to name them with uppercase, especially for environment variables or constants. This makes them stand out from regular shell commands or function names, which are typically lowercase. For example, APP_NAME and app_name are both allowed, but we should stick to APP_NAME.

APP_NAME=LARAVEL

app_name=laravel
Enter fullscreen mode Exit fullscreen mode

For variables in a function or a block, I define each of them with an underscore as the prefix. It helps me figure out their scope immediately.

greet() {
    local _NAME=$1

    echo "Hello $_NAME"
}

if [ ! -f hello.txt ]; then
    _FILE=hello.txt

    touch $_FILE
fi
Enter fullscreen mode Exit fullscreen mode

Using local makes a variable scope only inside the function.

There are a few special variables managed/assigned by the shell itself. E.g. $@, $?, $#,... For more information, please visit here.

Functions

In Bash, define and call a function is simple as this following example.

# greet is the function name.
# it is followed by ()
# the function body is enclosed in {}
greet() {
    if [ -z "$1" ]; then
        echo "Hello, World!"
    else
        echo "Hello, $1!"
    fi
}
Enter fullscreen mode Exit fullscreen mode

Call function greet without any parameters.

# 'Hello, World!' is displayed

greet
Enter fullscreen mode Exit fullscreen mode

Call function greet with a parameter.

# 'Hello, Alice!' is displayed

greet "Alice"
Enter fullscreen mode Exit fullscreen mode

As you can see, when calling a function, we can pass parameters into it by placing them after the function name (separated by spaces).

Inside the function, we have $1-$9 special variables depending on the number of parameters passed in runtime, up to 9 parameters.

concat_words() {
    echo "Do you know $1 $2 $3?"
}

# $1 is "Bash"
# $2 is "is"
# #3 is "cool"
# "Do you know Bash is cool?" is printed
concat_words "Bash" "is" "cool" 
Enter fullscreen mode Exit fullscreen mode

Expressions

Because most elements are treated as strings, expressions are designed to interact with numbers. An expression is enclosed in $(( and ))

A=9
B=3

SUM=$((A + B))
DIFFERENCE=$((A - B))
MULTIPLICATION=$((A * B))
DIVISION=$((A / B))

echo "A + B = $SUM"
echo "A - B = $DIFFERENCE"
echo "A * B = $MULTIPLICATION"
echo "A / B = $DIVISION"
Enter fullscreen mode Exit fullscreen mode

The result will be:

A + B = 12
A - B = 6
A * B = 27
A / B = 3
Enter fullscreen mode Exit fullscreen mode

if / else statements

Syntax

You've already seen if / else in previous sections. It's syntax like this.

if condition; then
    # Do something if the condition is true
fi

if condition; then
    # Do something if the condition is true
else
   # If condition is false
fi


if first_condition; then
    # Do something if the first_condition is true
elif second_condition; then
    # Do something if the second_condition is true
else
    # Do something if neither first or second condition is true
fi
Enter fullscreen mode Exit fullscreen mode

See this example for more details.

debug() {
    if [ -z "$1" ]; then
        echo "The debug mode is not set."
    elif [ "$1" = "on" ]; then
        echo "The debug mode is enabled."
    elif [ "$1" = "off" ]; then
        echo "The debug mode is disabled."
    else
        echo "The debug mode is invalid. Please use on/off."
    fi
}

debug
debug invalid
debug on
debug off
Enter fullscreen mode Exit fullscreen mode

Conditions

Check if a variable is not set using -z

if [ -z "$MESSAGE" ]; then
    echo "MESSAGE is not set."
fi
Enter fullscreen mode Exit fullscreen mode

! operator negates the condition.

if [ ! -z "$MESSAGE" ]; then
    echo "MESSAGE is set."
fi
Enter fullscreen mode Exit fullscreen mode

Check if a file or a directory exists.

if [ -d /var/log ]; then
    echo "/var/log exists as a directory."
fi

if [ -f /var/log/alternatives.log ]; then
    echo "/var/log/alternatives.log exists as a file."
fi
Enter fullscreen mode Exit fullscreen mode

Check if a function exists.

if declare -F greet > /dev/null ; then
    echo "greet is a function"
else
    echo "greet is not a function"
fi
Enter fullscreen mode Exit fullscreen mode

Check if a variable equals a string or another variable.

if [ "$BRANCH" = "main" ]; then
    echo "On main branch"
fi

if [ "$BRANCH" = "$REMOTE_BRANCH" ]; then
    echo "BRANCH and REMOTE_BRANCH have the same value."
fi
Enter fullscreen mode Exit fullscreen mode

! operator negates the condition.

if [ "$BRANCH" != "main" ]; then
    echo "Not on main branch"
fi
Enter fullscreen mode Exit fullscreen mode

Number comparisons.

# -ne : not equal
if [ "$NUMBER" -ne 0 ]; then
    echo "NUMBER is not 0."
fi

# -eq : equal
if [ "$NUMBER" -eq 0 ]; then
    echo "NUMBER = 0"
fi

# -gt : greater than
if [ "$NUMBER" -gt 0 ]; then
    echo "NUMBER > 0"
fi

# -lt : less than
if [ "$NUMBER" -lt 0 ]; then
    echo "NUMBER < 0"
fi
Enter fullscreen mode Exit fullscreen mode

Switch case

Switch case syntax in Bash is like this example.

case $CHOICE in
    'y')
        echo 'You type "y".'
    ;;
    'n')
        echo 'You type "n".'
    ;;
    *)
        echo 'Please type "y" or "n".'
    ;;
esac
Enter fullscreen mode Exit fullscreen mode

Loops

For loop syntax in Bash is like this example.

for COLOR in red green blue
do
    echo $COLOR
done
Enter fullscreen mode Exit fullscreen mode

While loop syntax in Bash is like this example.

CHOICE=y

# The loop will not stop until we type "exit".
while [ "$CHOICE" != 'exit' ]
do
    echo 'What is your choice?'
    read -r CHOICE
done
Enter fullscreen mode Exit fullscreen mode

Conclusion

These are all things about Bash I'm currently using. They help me automate my development and CI workflows easily. I think it's enough for now. If you have any other helpful cases, please share with me. I may update the post later when I found other things cool. :)

Top comments (0)