Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
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.
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.
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.
Use chmod to give your script execute permission:
chmod +x myscript.sh
Then run it with:
./myscript.sh
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.
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.
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
echo "My name is $NAME and I'm ${AGE} years old."
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.
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 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 => ${user_info<span class="hljs-selector-attr">[$key]</span>}"
done
<span class="hljs-selector-attr">
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:
Bash has your standard looping logic structures. If you’re already a programmer, there’s nothing out of the ordinary next.
Syntax:
for var in item1 item2 item3; do
echo $var
done
Example (looping over files):
for file in *.txt; do
echo "File: $file"
done
Syntax:
while [ condition ]; do
# Commands
done
Example:
COUNT=1
while [ $COUNT -le 5 ]; do
echo "Count: $COUNT"
((COUNT++))
done
Syntax:
until [ condition ]; do
# Commands
done
Works like while but continues until the condition becomes true.
Functions group commands into reusable blocks.
my_function() {
echo "Hello from my_function"
}
#Call it
my_function
Positional parameters inside a function:
Example:
greet() {
echo "Hello, $1"
}
greet "Alice"
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"
#!/usr/bin/env bash
NAME=$1
if [ -z "$NAME" ]; then
echo "Usage: $0 <name>"
exit 1
fi
echo "Hello, $NAME!"
#!/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:
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 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.
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.