Bash Versions
Not all Bash installations are the same. The version of Bash you are running matters — some features (associative arrays, mapfile, improved globbing) require Bash 4 or higher. This page explains the differences and how to handle them.
Checking Your Bash Version
bash --version
On Ubuntu 22.04:
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
On macOS Ventura/Sonoma (default):
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
Copyright (C) 2007 Free Software Foundation, Inc.
macOS ships Bash 3.2 — a version from 2007. This is not a mistake or oversight. It is intentional.
Why macOS Ships Bash 3.2
Apple ships Bash 3.2 because it is the last version released under GPL v2.
Bash 4.0 and later use GPL v3 — a licence that Apple’s legal team considers incompatible with macOS distribution. Rather than deal with GPL v3, Apple:
- Ships Bash 3.2 (GPL v2) as the default
- Switched the default interactive shell to
zshon macOS Catalina (2019)
The result: if you open a terminal on a Mac and type bash, you get version 3.2, which is missing many features. zsh is your interactive shell, and it is much more capable.
Key Features by Bash Version
Bash 3.x (macOS default — avoid for scripting)
- No associative arrays (
declare -A) - No
mapfile/readarray - Limited
[[ ]]support $'...'escape sequences (available)- Problem: Most modern Bash scripts expect Bash 4+
Bash 4.x — Major Feature Release (2009)
# Associative arrays (NOT available in Bash 3)
declare -A config
config[host]="localhost"
config[port]="5432"
echo "${config[host]}" # localhost
# mapfile — read file lines into an array
mapfile -t lines < /etc/hosts
echo "${lines[0]}" # 127.0.0.1 localhost
# Lowercase / uppercase string conversion
name="ALICE"
echo "${name,,}" # alice
echo "${name^^}" # ALICE (same, already uppercase)
Bash 5.x — Current Version (2019)
# Improved nameref variables (local -n)
function double_array() {
local -n ref=$1 # nameref — indirect reference to array
ref+=("${ref[@]}")
}
# BASH_ARGV0 — writable variable for $0
# Improved globbing with GLOBIGNORE
# Coprocesses improvements
# Check version in a script
if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then
echo "Error: Bash 4+ required" >&2
exit 1
fi
Version Feature Comparison
| Feature | Bash 3.x | Bash 4.x | Bash 5.x |
|---|---|---|---|
Associative arrays (declare -A) |
❌ | ✅ | ✅ |
mapfile / readarray |
❌ | ✅ | ✅ |
${var,,} lowercase conversion |
❌ | ✅ | ✅ |
${var^^} uppercase conversion |
❌ | ✅ | ✅ |
globstar (**) |
❌ | ✅ | ✅ |
nameref (local -n) |
❌ | ⚠️ Partial | ✅ |
BASH_ARGV0 |
❌ | ❌ | ✅ |
Installing Bash 5 on macOS
If you are writing Bash scripts on a Mac, install a modern Bash with Homebrew:
# Install Homebrew first (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install modern Bash
brew install bash
# Verify
/opt/homebrew/bin/bash --version
# GNU bash, version 5.2.x...
# Add to allowed shells
echo "/opt/homebrew/bin/bash" | sudo tee -a /etc/shells
# (Optional) change your login shell to Bash 5
chsh -s /opt/homebrew/bin/bash
Update your script shebangs to use env for portability:
#!/usr/bin/env bash
# This picks up whichever bash is first in $PATH
# On macOS with Homebrew bash installed first, this will use Bash 5
Checking Version in Scripts
Add this guard to scripts that require Bash 4+:
#!/usr/bin/env bash
set -euo pipefail
# Require Bash 4 or higher
if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then
echo "Error: This script requires Bash 4 or higher." >&2
echo "Current version: ${BASH_VERSION}" >&2
exit 1
fi
BASH_VERSINFO is an array:
[0] = major version (e.g., 5)
[1] = minor version (e.g., 1)
[2] = patch level (e.g., 16)
[3] = build version (e.g., 1)
[4] = release status (e.g., release)
[5] = machine type (e.g., x86_64-pc-linux-gnu)
Key Takeaways
- Ubuntu 22.04 ships Bash 5.1 — full featured
- macOS ships Bash 3.2 by default — limited, due to GPL licensing
- Bash 4 added: associative arrays,
mapfile, string case conversion,globstar - Always use
#!/usr/bin/env bashin scripts for portability - Add a version check guard in scripts that require Bash 4+
- Install Bash 5 via Homebrew on macOS for modern scripting
| ← Back to Bash vs sh vs zsh vs fish | Next → The Terminal Emulator |