A guide to Bash scripting by topic with examples: variables and expansion, control flow, functions, error handling, file operations, arrays and maps, debugging and best practices.
Use it when
You are writing or reviewing a shell script.
You need a safe idiom for a common scripting task.
Watch out for
Bash-specific features (arrays, [[ ]]) are not available in POSIX sh; set the shebang accordingly.
Use set -euo pipefail and quote variables, and consider a different language for complex logic.
The data
Sections
8 rows
Topic
Examples
Variables and Expansion
4 rows
Name
Code
Simple assignment
name="John"
echo "Hello, $name"
Command substitution
current_dir=$(pwd)
echo "We are in $current_dir"
Default values
echo "${PORT:-8080}" # prints 8080 if PORT unset
echo "${PORT:=8080}" # sets PORT to 8080 if unset
echo "${PORT:?Error: PORT required}" # exits if unset
if ! command -v docker &> /dev/null; then
echo "Docker is not installed"
exit 1
fi
File Operations
3 rows
Name
Code
Read file line by line
while IFS= read -r line; do
echo "$line"
done < "input.txt"
Check file conditions
if [ -f "$file" ]; then echo "regular file"; fi
if [ -d "$dir" ]; then echo "directory"; fi
if [ -x "$bin" ]; then echo "executable"; fi
if [ -z "$str" ]; then echo "empty string"; fi
if [ -n "$str" ]; then echo "non-empty"; fi
Temp files
tempfile=$(mktemp)
echo "Writing to $tempfile"
# ... use it ...
rm -f "$tempfile"
Arrays and Maps
2 rows
Name
Code
Indexed array
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}" # apple
echo "${#fruits[@]}" # length 3
echo "${fruits[@]}" # all elements
Associative array (Bash 4+)
declare -A config
config["host"]="localhost"
config["port"]=8080
echo "${config[host]}" # localhost
Debugging
3 rows
Name
Code
Enable debug mode
set -x # Print commands and their arguments as executed
# ... debug code ...
set +x # Disable debug
# Or run script with:
# bash -x script.sh
Check syntax without running
bash -n script.sh
# Returns silently if syntax is valid
usage() {
cat <<EOF
Usage: $0 [options]
-h Show help
-v Verbose mode
-f Input file
EOF
exit 1
}
while getopts "hf:v" opt; do
case $opt in
h) usage;;
f) file="$OPTARG";;
v) verbose=true;;
*) usage;;
esac
done
Portable scripting
# Prefer POSIX sh -c over bashisms when portability matters
# Use printf instead of echo for consistent behavior
# Quote all variable expansions
# Use $(...) over backticks
Fields
The shape of this dataset, read from the data itself: every column, its type and a real value. Agents can use this to plan a query without fetching the whole document.
Section
Field
Type
Example
sections
topic
string
Variables and Expansion
sections
examples
array
[4 items]
Fetch the same bytes
The static files contain the same reference rows as the API, with no API rate limit.
Live metadata, such as view counts, may differ. Use the API for content negotiation;
use the static files for a cacheable snapshot.