All skills
Skillintermediate
Bash Reference Guide
Bash (Bourne Again SHell) is a Unix shell and command language. This guide covers bash-specific features, syntax, and best practices.
Claude Code Knowledge Pack7/10/2026
Overview
Bash Reference Guide
Overview
Bash (Bourne Again SHell) is a Unix shell and command language. This guide covers bash-specific features, syntax, and best practices.
Official Documentation: https://www.gnu.org/software/bash/manual/
Bash vs POSIX Shell (sh)
Bash is a superset of POSIX sh with many extensions. Not all bash scripts are POSIX-compliant.
Bash-Specific Features (NOT in POSIX sh)
-
Arrays
# Bash only array=(one two three) echo "${array[0]}" declare -a indexed_array declare -A associative_array -
[[ ]] Test Construct
# Bash only - more powerful than [ ] if [[ "$var" == pattern* ]]; then echo "Matches pattern" fi # POSIX sh - use [ ] if [ "$var" = "exact" ]; then echo "Exact match" fi -
Process Substitution
# Bash only diff <(ls dir1) <(ls dir2) -
Brace Expansion
# Bash only echo {1..10} # Outputs: 1 2 3 4 5 6 7 8 9 10 mv file.{txt,bak} # Renames file.txt to file.bak -
Function Keyword
# Bash style (function keyword optional) function myfunction { echo "Hello" } # POSIX sh style (no function keyword) myfunction() { echo "Hello" } -
Local Variables
# Bash only function myfunc { local var="value" echo "$var" } -
Extended Pattern Matching
shopt -s extglob # Bash only ?(pattern-list) # Matches zero or one occurrence *(pattern-list) # Matches zero or more occurrences +(pattern-list) # Matches one or more occurrences @(pattern-list) # Matches one occurrence !(pattern-list) # Matches anything except pattern -
Advanced Parameter Expansion
# Bash supports more advanced parameter expansion ${var,,} # Lowercase ${var^^} # Uppercase ${var:0:5} # Substring ${var/pattern/replacement} # Replace first ${var//pattern/replacement} # Replace all -
Source vs Dot
source script.sh # Bash (also works: . script.sh) . script.sh # POSIX sh -
Bash Built-in Variables
$RANDOM # Random number $SECONDS # Seconds since script started $BASH_VERSION $BASH_SOURCE $FUNCNAME $DIRSTACK
Core Bash Syntax
Variables
# Assignment (no spaces around =)
var="value"
readonly CONST="constant"
declare -i integer=42
declare -r readonly_var="const"
declare -x export_var="exported"
# Reading variables
echo "$var"
echo "${var}" # Preferred for clarity
# Command substitution
result=$(command)
result=`command` # Deprecated, use $() instead
# Arithmetic
result=$((5 + 3))
((var++))
((var += 5))
Quoting Rules
# Double quotes: Preserve literal value except $, `, \\, and !
echo "Value: $var"
# Single quotes: Preserve literal value of all characters
echo 'Value: $var' # Outputs: Value: $var
# No quotes: Word splitting and pathname expansion
files=$var # Dangerous if var contains spaces
# Always quote variable expansions unless you need word splitting
cp "$file" "$destination"
Control Structures
# If statement
if [[ condition ]]; then
# commands
elif [[ condition ]]; then
# commands
else
# commands
fi
# Case statement
case "$var" in
pattern1)
# commands
;;
pattern2|pattern3)
# commands
;;
*)
# default
;;
esac
# For loops
for item in list; do
echo "$item"
done
for ((i=0; i<10; i++)); do
echo "$i"
done
# While loop
while [[ condition ]]; do
# commands
done
# Until loop
until [[ condition ]]; do
# commands
done
Functions
# Function definition
function_name() {
local local_var="value"
echo "$1" # First argument
return 0 # Exit status
}
# Call function
function_name arg1 arg2
# Function with return value (via stdout)
get_value() {
echo "returned value"
}
result=$(get_value)
Error Handling
# Exit on error
set -e
set -o errexit
# Exit on undefined variable
set -u
set -o nounset
# Pipe failure detection
set -o pipefail
# Combining options
set -euo pipefail
# Trap errors
trap 'echo "Error on line $LINENO"' ERR
# Trap exit
trap cleanup EXIT
cleanup() {
# Cleanup code
rm -f "$temp_file"
}
Input/Output Redirection
# Redirect stdout
command > file
# Redirect stderr
command 2> errors.txt
# Redirect both
command &> output.txt
command > output.txt 2>&1
# Append
command >> file
# Here document
cat </dev/null; then
echo "ShellCheck is installed"
fi
6. Use [[ ]] for Tests
# Preferred in bash
if [[ "$var" == "value" ]]; then
# ...
fi
# Use [ ] only for POSIX compliance
if [ "$var" = "value" ]; then
# ...
fi
7. Handle Errors Appropriately
if ! command; then
echo "Command failed" >&2
exit 1
fi
command || { echo "Failed" >&2; exit 1; }
8. Use Meaningful Variable Names
# Good
user_count=10
max_retries=3
# Bad
n=10
x=3
9. Add Comments
# Explain complex logic
# Document function parameters
# Clarify non-obvious behavior
10. Use Functions for Reusability
log_error() {
echo "[ERROR] $*" >&2
}
log_info() {
echo "[INFO] $*"
}
Common Pitfalls
1. Unquoted Variables
# Wrong
file=/path/with spaces/file.txt
cat $file # Fails!
# Right
file="/path/with spaces/file.txt"
cat "$file"
2. Not Checking Return Codes
# Wrong
cd /some/directory
rm -rf * # Dangerous if cd fails!
# Right
cd /some/directory || exit 1
rm -rf *
3. Using [ ] with Bash Features
# Wrong
if [ "$var" == pattern* ]; then # == not in POSIX
# Right (bash)
if [[ "$var" == pattern* ]]; then
# Right (POSIX)
if [ "$var" = "exact" ]; then
4. Word Splitting Issues
# Wrong
files=$(ls *.txt)
for file in $files; do # Breaks on spaces
echo "$file"
done
# Right
for file in *.txt; do
echo "$file"
done
5. Not Using Local in Functions
# Wrong - pollutes global scope
function bad {
var="value"
}
# Right
function good {
local var="value"
}
Parameter Expansion Reference
${var} # Value of var
${var:-default} # Use default if var is unset
${var:=default} # Assign default if var is unset
${var:?error} # Error if var is unset
${var:+alternate} # Use alternate if var is set
${#var} # Length of var
${var:offset:length} # Substring
${var#pattern} # Remove shortest match from beginning
${var##pattern} # Remove longest match from beginning
${var%pattern} # Remove shortest match from end
${var%%pattern} # Remove longest match from end
${var/pattern/replacement} # Replace first match
${var//pattern/replacement} # Replace all matches
${var^} # Uppercase first character
${var^^} # Uppercase all
${var,} # Lowercase first character
${var,,} # Lowercase all
Special Variables
$0 # Script name
$1-$9 # Positional parameters
${10} # 10th parameter (braces required)
$# # Number of positional parameters
$* # All positional parameters (as single word)
$@ # All positional parameters (as separate words)
$$ # Process ID of shell
$! # PID of last background command
$? # Exit status of last command
$_ # Last argument of previous command