Bash vs Zsh for scripting
Zsh is a great interactive shell but Bash is the better choice for portable shell scripts. Here is why, with concrete examples of where Zsh-isms break.
Tldr
Use Zsh for your interactive shell if you like it; use Bash for scripts. Zsh has nicer interactive features but its scripting language differs from Bash in subtle ways (word splitting defaults, glob behavior, array indexing) that break portability. Bash is preinstalled on virtually every Linux distro; Zsh is not.
Sections
Heading
Where they diverge
Body
Zsh does NOT split unquoted variables by default — `$var` stays as one word even if it contains spaces. Bash splits on IFS. Zsh arrays are 1-indexed; Bash arrays are 0-indexed. Zsh has its own glob qualifiers and recursive globs (**/*.txt) without needing globstar. Each of these is a source of subtle bugs when copying scripts between shells.
Heading
Where Bash wins for scripts
Body
Ubiquity — Bash is on every Linux distribution, every cloud VM image, every CI runner. macOS still ships Bash (an old version, but it is there). Zsh is the default interactive shell on macOS now but is not guaranteed on Linux. If you write a script that may run on someone else's machine, Bash gives you the broadest compatibility.
Heading
Where Zsh wins for interactive use
Body
Better tab completion, themeable prompts (powerlevel10k, oh-my-zsh), recursive globs without ceremony, spelling correction, shared command history across sessions. None of these matter inside a script — they matter at the prompt.
Heading
Migration tips
Body
If you maintain a Zsh script and want to make it portable, replace `${array[1]}` with `${array[0]}`, quote every variable expansion ("$var" not $var), replace **/*.ext with `find . -name "*.ext"`, and run it through shellcheck with --shell=bash.
Verdict
Write scripts in Bash, use Zsh interactively if you like it. The 30 minutes of "Zsh is so nice" do not pay back the hours of debugging portability bugs.
Faq
Q
Is Zsh faster than Bash for scripts?
A
Marginally for some operations, slower for others. The difference rarely matters compared to the cost of forked subprocesses inside the script.
Q
Can I use a Bash script in Zsh?
A
If the shebang is #!/usr/bin/env bash and bash is installed, yes — the shebang determines the interpreter regardless of your interactive shell.
Q
What about fish?
A
Fish is not POSIX-compatible at all — scripts are not portable between fish and Bash. Use fish interactively if you like it; do not write production scripts in it.