Bash shell

Bash scripting guide and cheat sheet

While there are many tutorials about Bash scripting on the Internet, this one focuses on presenting the information in a cheat sheet style, so you can jump right into coding without wasting your time. From the very beginning to intermediate and advanced topics.

Introduction

Bash (Bourne Again SHell) is a command interpreter for Unix-like systems. It provides a powerful scripting language that automates tasks, manages system operations, and processes data. By writing Bash scripts, you can save time on repetitive or complex tasks while maintaining portability across many environments.

Bash scripting is commonly used for server administration, DevOps tasks, and even everyday desktop automation. It supports variables, functions, conditionals, loops, and many other programming constructs, making it both straightforward for simple tasks and flexible enough for more advanced projects.

Bash scripting is a core skill for Linux users and system administrators, allowing for efficient task automation and streamlining of workflows. With a knowledge of variables, arrays, conditionals, loops, and functions, you can quickly build versatile scripts. Combine these with external commands and command substitution to create robust solutions for daily or production-level tasks.


Getting Started

The following section will guide you through the creation and configuration of the script itself, so you can actually set it up and make it executable.

Shebang

A shebang is the first line of most scripts and indicates which shell or interpreter will run the script. For Bash, it’s usually:

#!/usr/bin/env bash

Place this at the beginning of your script (e.g., myscript.sh) to ensure it uses Bash rather than another shell.

Making a Script Executable

Use chmod to give your script execute permission:

chmod +x myscript.sh

Then run it with:

./myscript.sh

Putting It All Together

Don’t worry if you’re still lost, at the end of this guide we’ve included a section called Putting It All Together that will teach you how to use your scripts once you create or download them.


Variables and Parameter Expansion

Originally Bash only had simple variables, but with version 4.0 and on it introduced arrays. This section will tech you how to use variables and expand parameters, the next section will teach you how to use arrays.

Declaring Variables

Variables in Bash do not require a specific type. By default, they’re treated as strings.

Example:

NAME="Pietro"
AGE=30

Access the variable with a leading dollar sign:

echo $NAME

# Pietro will be echoed out to the console

Quoting

  • Double quotes (” “): Expand variables inside.
  • Single quotes (‘ ‘): Interpret literally (no expansion).
  • Backticks or $( ): Command substitution.

Special Variables

  • $0: The name of the script itself.
  • $1, $2, …: Positional parameters (arguments to the script).
  • $#: Number of positional parameters.
  • $@: All positional parameters (individually quoted).
  • $?: Exit status of the last command.

Parameter Expansion Examples

echo "My name is $NAME and I'm ${AGE} years old."

Data Structures

As we mentioned in the previous section, originally Bash’s data storing capabilities (in the form of variables) were limited, but eventually Arrays were added and with Bash version 4.0 Associative Arrays were added, turning Bash into a complex and complete programming language.

Arrays

Indexed Arrays

Indexed arrays use numerical indices starting at 0.

# Declare and initialize
my_array=(<span class="hljs-string">"first"</span> <span class="hljs-string">"second"</span> <span class="hljs-string">"third"</span>)

# Access elements
echo <span class="hljs-string">"${my_array[0]}"</span>   # first

# Modify elements
my_array[<span class="hljs-number">1</span>]=<span class="hljs-string">"new_second"</span>
echo <span class="hljs-string">"${my_array[1]}"</span>   # new_second

# Add element
my_array[<span class="hljs-number">3</span>]=<span class="hljs-string">"fourth"</span>

Looping over an indexed array:

for element in <span class="hljs-string">"${my_array[@]}"</span>; do
echo "$element"
done
<span class="hljs-selector-attr">

Associative Arrays (Bash 4.0+)

Associative arrays use string keys instead of numeric indices.

# Declare an associative array
declare -<span class="hljs-selector-tag">A</span> user_info

# Assign values
user_info<span class="hljs-selector-attr">[<span class="hljs-string">"name"</span>]</span>="Alice"
user_info<span class="hljs-selector-attr">[<span class="hljs-string">"id"</span>]</span>="<span class="hljs-number">1234</span>"
user_info<span class="hljs-selector-attr">[<span class="hljs-string">"role"</span>]</span>="admin"

# Access and print
echo "Name: ${user_info<span class="hljs-selector-attr">[<span class="hljs-string">"name"</span>]</span>}"
echo "ID: ${user_info<span class="hljs-selector-attr">[<span class="hljs-string">"id"</span>]</span>}"
echo "Role: ${user_info<span class="hljs-selector-attr">[<span class="hljs-string">"role"</span>]</span>}"

# Loop through keys
for key in "${!user_info<span class="hljs-selector-attr">[@]</span>}"; do
echo "$key =&gt; ${user_info<span class="hljs-selector-attr">[$key]</span>}"
done
<span class="hljs-selector-attr">

Conditional Statements

if-then-else

Syntax:

if [ condition ]; then
# Commands if condition is true
elif [ another_condition ]; then
# Commands if another_condition is true
else
# Commands otherwise
fi

Example:

if [ $AGE -gt 18 ]; then
echo "Adult"
else
echo "Minor"
fi

Common test operators:

  • -eq, -ne, -lt, -le, -gt, -ge for integer comparison
  • =, != for string comparison
  • -z checks if a string is empty
  • -n checks if a string is not empty
  • -f checks if a file exists
  • -d checks if a directory exists

Looping Structures

Bash has your standard looping logic structures. If you’re already a programmer, there’s nothing out of the ordinary next.

for Loop

Syntax:

for var in item1 item2 item3; do
echo $var
done

Example (looping over files):

for file in *.txt; do
echo "File: $file"
done

while Loop

Syntax:

while [ condition ]; do
# Commands
done

Example:

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

until Loop

Syntax:

until [ condition ]; do
# Commands
done

Works like while but continues until the condition becomes true.


Functions

Defining and Calling Functions

Functions group commands into reusable blocks.

my_function() {
echo "Hello from my_function"
}
#Call it
my_function

Positional parameters inside a function:

  • $1: first argument to the function
  • $2: second argument, etc.

Example:

greet() {
echo "Hello, $1"
}

greet "Alice"

Working with External Commands

You can run external commands within your scripts. Capture command output using command substitution:

DATE=$(date +%Y-%m-%d)
echo "Today is $DATE"

Use && or || to chain commands based on success/failure:

DATE=$(date +%Y-%m-%d)
echo "Today is $DATE"

Putting It All Together (Script Examples)

Example 1: Greeting Script

#!/usr/bin/env bash
NAME=$1
if [ -z "$NAME" ]; then
echo "Usage: $0 <name>"
exit 1
fi

echo "Hello, $NAME!"

Example 2: Backup Script

#!/usr/bin/env bash
SOURCE_DIR="/path/to/source"
BACKUP_DIR="/path/to/backup"
DATE=$(date +%Y-%m-%d)

if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR"
fi

tar -czf "$BACKUP_DIR/backup-$DATE.tar.gz" "$SOURCE_DIR"
echo "Backup completed: $BACKUP_DIR/backup-$DATE.tar.gz"

In this script:

  1. We define the source directory (SOURCE_DIR) and backup directory (BACKUP_DIR).
  2. Create the backup directory if it doesn’t exist.
  3. Compress and archive the source directory with tar.

Advanced Bash Scripting

From advanced parameter expansion techniques, process substitution and signal handling to namerefs and indirection, advanced argument parsing, I/O redirection and even parallelization. Take bash scripting to the next level.

You can access the Advanced Bash scripting topics following this link: Advanced Bash Scripting Guide, Cheat Sheet and Use Cases.


Command Substitution

Command substitution in Bash allows you to capture the output of a command and store it in a variable or use it directly within another command.

For the full guide on Command Substitution in Bash, follow this link: Command Substitution in Bash.


Bash Scripts Debugging and Troubleshooting

Various techniques and tools for troubleshooting and debugging your Bash scripts. We’ll cover both built-in approaches (like set options and trap) and external resources (shellcheck, logs) to help you quickly identify and fix issues.

You can access the Bash Debugging Guide following this link: Debugging and Troubleshooting Your Bash Scripts.

Leave a Reply

Your email address will not be published. Required fields are marked *