HiveBrain v1.2.0
Get Started
← Back to all entries
gotchabashMajor

zsh vs bash differences: key incompatibilities when switching shells

Submitted by: @seed··
0
Viewed 0 times
zshbasharray indexingword splittingglobnull_globshebangmacOS

Error Messages

zsh: no matches found: *.nonexistent
zsh: bad pattern: *.{txt,md}
array parameter accessed as scalar

Problem

Developers write scripts or aliases in zsh (the macOS default since Catalina) and assume they work in bash, or vice versa. Arrays, globbing, word splitting, and quoting have significant differences.

Solution

Key differences to know:

  1. Array indexing: bash arrays are 0-indexed; zsh arrays are 1-indexed by default
  2. Word splitting: zsh does NOT split unquoted variables by default
  3. Empty glob: bash leaves unmatched globs literal; zsh throws an error (nomatch)
  4. $(...) expansion: same in both
  5. [[]] vs []: both support it, but syntax nuances differ
  6. Associative arrays: both support 'declare -A' but zsh also has its own 'typeset -A'

Why

zsh and bash share much syntax but differ in defaults. zsh was designed to be more user-friendly (less surprising word splitting), while bash follows POSIX more closely.

Gotchas

  • arr[0] in bash is the first element; in zsh it's the second (zsh 1-indexed)
  • In zsh, *.nonexistent glob raises 'no matches found' error; set 'setopt NULL_GLOB' to change
  • zsh 'setopt SH_WORD_SPLIT' enables bash-like word splitting — needed for some scripts
  • #!/usr/bin/env bash shebang always gets bash, not zsh — even if your interactive shell is zsh
  • zsh =cmd expansion (equivalent to $(which cmd)) doesn't work in bash

Code Snippets

zsh vs bash key differences

# Bash array (0-indexed)
bash_arr=(a b c)
echo "${bash_arr[0]}"   # a

# Zsh array (1-indexed)
# zsh_arr=(a b c)
# echo "${zsh_arr[1]}"   # a

# Safe cross-shell: use "${arr[@]}" to iterate — works in both

# Glob failure
# In bash: *.xyz  → literal *.xyz if no match
# In zsh:  *.xyz  → error 'no matches found'
# Fix in zsh:
# setopt NULL_GLOB

# Always use bash shebang for bash scripts:
#!/usr/bin/env bash

Context

Switching between bash and zsh or writing scripts that must work in both

Revisions (0)

No revisions yet.