🐚 Bash Differences Reference
Understanding the differences between Bash and other shells is crucial for writing portable scripts and leveraging Bash-specific features effectively. This reference highlights key distinctions and capabilities.
🎯 Major Bash Features
Arrays
Bash supports indexed and associative arrays, unlike POSIX sh.
1
2
3
4
5
6
7
8
9
10
11
12 | # Indexed arrays (Bash 2.0+)
fruits=("apple" "banana" "cherry")
fruits[3]="date"
echo "${fruits[0]}" # apple
echo "${fruits[@]}" # all elements
echo "${#fruits[@]}" # array length
# Associative arrays (Bash 4.0+)
declare -A userinfo
userinfo[name]="John"
userinfo[age]=30
echo "${userinfo[name]}"
|
Advanced Parameter Expansion
Extended parameter manipulation capabilities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | var="Hello World"
# Case conversion (Bash 4.0+)
echo "${var^^}" # HELLO WORLD (upper)
echo "${var,,}" # hello world (lower)
# Pattern removal
echo "${var#Hello }" # World (remove shortest from front)
echo "${var##Hello }" # World (remove longest from front)
echo "${var% World}" # Hello (remove shortest from back)
echo "${var%% World}" # Hello (remove longest from back)
# Pattern replacement
echo "${var/World/Universe}" # Hello Universe
echo "${var//o/O}" # HellO WOrld (global replace)
|
Extended Test Conditions
Enhanced conditional expressions with [[ ]].
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | # Pattern matching
if [[ "$file" == *.txt ]]; then
echo "Text file"
fi
# Regular expressions
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Valid email"
fi
# String operations
if [[ -n "$string" && "$string" != "test" ]]; then
echo "Valid string"
fi
|
🔧 Process Management Extensions
Process Substitution
Execute commands and treat output as files.
1
2
3
4
5
6
7
8
9
10
11
12 | # Compare sorted outputs
diff <(sort file1.txt) <(sort file2.txt)
# Read from command output
while read line; do
echo "Processing: $line"
done < <(find . -name "*.log")
# Write to command input
cat > >(gzip > output.gz) << EOF
Large content here
EOF
|
Coprocesses
Bidirectional communication with background processes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # Start coprocess
coproc SORT { sort; }
# Send data
echo "banana" >&"${SORT[1]}"
echo "apple" >&"${SORT[1]}"
echo "cherry" >&"${SORT[1]}"
# Close input
exec {SORT[1]}>&-
# Read results
while read line <&"${SORT[0]}"; do
echo "Sorted: $line"
done
|
📊 Advanced I/O Features
Here Strings
Pass strings directly as input.
| # Instead of echo "string" | command
grep "pattern" <<< "search in this string"
# Multiple lines
wc -l <<< $'line1\nline2\nline3'
|
Redirection Enhancements
Advanced redirection capabilities.
| # Redirect to multiple outputs
tee >(gzip > file.log.gz) >(logger -t myapp) > file.log
# Close file descriptors
exec 3<&- # Close FD 3
# Move file descriptors
exec 3<&0 # Save stdin to FD 3
exec 0</dev/null # Redirect stdin to /dev/null
exec 0<&3 # Restore stdin from FD 3
exec 3<&- # Close FD 3
|
🎨 Programming Constructs
Function Features
Enhanced function capabilities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | # Local variables with assignment
myfunc() {
local var="local value"
local assigned_var
assigned_var=$(date)
echo "$var - $assigned_var"
}
# Function attributes (Bash 4.2+)
readonly -f myfunc # Make function readonly
# Function recursion with local scope
factorial() {
local n=$1
if (( n <= 1 )); then
echo 1
else
local n_minus_one=$((n - 1))
local sub_result
sub_result=$(factorial $n_minus_one)
echo $((n * sub_result))
fi
}
|
Arithmetic Evaluation
Advanced mathematical operations.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | # Arithmetic evaluation with (( ))
x=5
if (( x > 3 && x < 10 )); then
echo "x is between 3 and 10"
fi
# Bitwise operations
(( result = 5 << 2 )) # Left shift: 20
(( result = 15 & 7 )) # Bitwise AND: 7
# Increment/decrement
(( x++ ))
(( ++y ))
# Compound assignments
(( x += 5 ))
(( y *= 2 ))
|
🔍 Pattern Matching and Globbing
Extended Globbing
Advanced pattern matching features.
1
2
3
4
5
6
7
8
9
10
11
12 | # Enable extended globbing
shopt -s extglob
# Extended patterns
ls !(pattern) # Not matching pattern
ls +(pattern) # One or more occurrences
ls *(pattern) # Zero or more occurrences
ls ?(pattern) # Zero or one occurrence
ls @(pattern1|pattern2) # Either pattern1 or pattern2
# Example
ls !(test*|*.tmp) # All files except those starting with test or ending with .tmp
|
Brace Expansion
Generate arbitrary strings.
1
2
3
4
5
6
7
8
9
10
11
12 | # Simple sequences
echo {1..10} # 1 2 3 4 5 6 7 8 9 10
echo {a..z} # a b c ... x y z
# Zero-padded sequences
echo {01..10} # 01 02 03 ... 09 10
# Nested brace expansion
echo {a,b}{1,2} # a1 a2 b1 b2
# Combining with other text
echo file{1..3}.txt # file1.txt file2.txt file3.txt
|
🛠️ Bash-Specific Builtins
Advanced Builtins
Bash-specific command-line utilities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | # Complete - programmable completion
complete -F _my_completion mycommand
# Coproc - coprocess management
coproc myproc { while read line; do echo "Got: $line"; done; }
# Disown - remove jobs from job table
long_running_command &
disown %1
# Hash - remember command locations
hash -p /custom/path/command custom_command
# Jobs - job control
jobs -l # List jobs with PIDs
jobs -r # List running jobs
jobs -s # List stopped jobs
|
Shell Options
Bash-specific shell behavior control.
| # Useful shopt options
shopt -s cdspell # Correct minor spelling errors in cd
shopt -s checkwinsize # Check window size after each command
shopt -s cmdhist # Save multi-line commands in history
shopt -s dotglob # Include dotfiles in pathname expansion
shopt -s expand_aliases # Expand aliases
shopt -s extglob # Enable extended pattern matching
shopt -s failglob # Fail on unmatched globs
shopt -s globstar # Enable ** globbing (Bash 4.0+)
shopt -s histappend # Append to history file
shopt -s interactive_comments # Allow comments in interactive mode
|
📋 Version-Specific Features
Bash 4.x Features
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | # Associative arrays
declare -A config
config[database]="mysql"
config[port]=3306
# Case conversion
name="John Doe"
echo "${name,,}" # john doe
echo "${name^^}" # JOHN DOE
# Globstar
shopt -s globstar
for file in **/*.txt; do
echo "$file"
done
# nameref (Bash 4.3+)
declare -n ref=original_var
ref="new value" # Modifies original_var
|
Bash 5.x Features
| # Array slice assignment
arr=(a b c d e)
arr[1...3]=("x" "y" "z") # Assign to indices 1,2,3
# Improved error messages
# Better diagnostic information for various error conditions
# Enhanced programmable completion
# More flexible completion functions
|
⚠️ Bashisms to Avoid for Portability
Non-Portable Features
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | # ❌ Arrays (use delimited strings instead)
items=(item1 item2 item3)
# ✅ Portable alternative
ITEMS="item1,item2,item3"
IFS=',' read -ra item_array <<< "$ITEMS"
# ❌ [[ ]] (use [ ] instead)
if [[ "$var" == pattern ]]; then
# ✅ Portable alternative
case "$var" in
pattern)
# match action
;;
esac
# ❌ Process substitution
diff <(sort file1) <(sort file2)
# ✅ Portable alternative
temp1=$(mktemp)
temp2=$(mktemp)
sort file1 > "$temp1"
sort file2 > "$temp2"
diff "$temp1" "$temp2"
rm "$temp1" "$temp2"
# ❌ Extended parameter expansion
echo "${var^^}"
# ✅ Portable alternative
echo "$var" | tr '[:lower:]' '[:upper:]'
|
🧾 Summary Comparison
Feature Matrix
| Feature |
Bash |
POSIX sh |
ksh |
zsh |
| Arrays |
✅ Indexed/Associative |
❌ |
✅ Indexed |
✅ Indexed/Associative |
[[ ]] |
✅ |
❌ |
✅ |
✅ |
| Process Substitution |
✅ |
❌ |
✅ |
✅ |
| Extended Globbing |
✅ (extglob) |
❌ |
✅ |
✅ |
| Brace Expansion |
✅ |
Limited |
✅ |
✅ |
| Here Strings |
✅ |
❌ |
✅ |
✅ |
| Coprocesses |
✅ |
❌ |
✅ |
✅ |
| Case Conversion |
Bash 4.0+ |
❌ |
❌ |
✅ |
| Name References |
Bash 4.3+ |
❌ |
❌ |
✅ |
When to Use Bash Features
✅ Use Bash-specific features when:
- Targeting Bash environments specifically
- Need advanced array operations
- Require pattern matching beyond basic globbing
- Want improved error handling and debugging
- Leveraging interactive shell enhancements
❌ Avoid Bash-specific features when:
- Writing portable scripts for multiple systems
- Targeting minimal environments (containers, embedded)
- Need maximum compatibility with other shells
- Following strict POSIX compliance requirements
🧠 Best Practices
Bash Usage Guidelines
- Explicit Shell Declaration: Use
#!/bin/bash for Bash-specific scripts
- Version Checking: Check Bash version for newer features
- Feature Testing: Use
shopt and conditional checks
- Documentation: Clearly document Bash-specific requirements
- Fallbacks: Provide portable alternatives when possible
- Testing: Test across different Bash versions
- Security: Be cautious with dynamic features like
eval
Version Compatibility Check
| # Check Bash version
if [[ ${BASH_VERSION%%.*} -lt 4 ]]; then
echo "Bash 4.0 or higher required" >&2
exit 1
fi
# Check for specific features
if ! shopt -q extglob; then
shopt -s extglob
fi
|
🧾 See Also