Ubuntu Adopts Dash as Default /bin/sh, Exposing Bashisms Everywhere
Ubuntu 6.10 switched its default /bin/sh from Bash to the stricter Dash in October 2006 for faster boot times, surfacing years of non-portable scripts.
With Ubuntu 6.10, released in October 2006, Ubuntu switched its default /bin/sh from Bash to Dash (the Debian Almquist Shell) — a change made purely for performance reasons that ended up surfacing a huge number of latent shell scripting bugs across the wider ecosystem.
Why the switch happened at all
Dash is a considerably smaller, stricter, POSIX-focused shell than Bash — with far less startup overhead, meaningfully speeding up boot-time script execution, which mattered enough at system-startup scale (many scripts run during boot, each incurring shell startup cost) to justify making it the new default /bin/sh.
What this immediately exposed: bashisms everywhere
Because /bin/sh had effectively been Bash for so long on most systems, an enormous number of scripts shebanged as #!/bin/sh had, over the years, quietly accumulated Bash-specific syntax — array usage, [[ ]] tests, and other extensions that Dash, as a strict POSIX shell, simply doesn’t support. Once /bin/sh actually pointed to Dash, these scripts started failing, sometimes with confusing errors rather than a clear “unsupported syntax” message.
Debian’s more cautious, later adoption of the same change
Debian, upstream of Ubuntu, took a considerably more cautious approach to the same underlying question — Debian didn’t adopt Dash as its own default /bin/sh until Debian 6 (“Squeeze”), released in February 2011, roughly four and a half years after Ubuntu’s switch, giving package maintainers considerably more time to identify and fix bashisms in their own scripts first.
The lasting practical consequence for anyone writing shell scripts
This transition is a large part of why “don’t assume /bin/sh is Bash” became, and remains, standard, repeated advice in shell scripting guidance — a script working perfectly on a developer’s own machine (where /bin/sh might well be Bash) can fail entirely once deployed to, or executed within, an environment using a strict /bin/sh implementation like Dash instead.
The tool that emerged specifically to catch this class of bug automatically
Debian’s response to the same underlying problem wasn’t only a slower, more cautious rollout timeline — the project also maintains checkbashisms, a script bundled in the devscripts package that scans a #!/bin/sh script and flags shell syntax that works under Bash but isn’t guaranteed by POSIX, distinguishing genuine portability bugs from Debian Policy’s own permitted extensions. Running it against a script before deployment catches exactly the class of bug Ubuntu’s 2006 switch exposed at scale, turning “did I accidentally use a bashism in a POSIX-shebanged script” from a question only discovered at runtime, on whichever system happened to run it, into something checkable automatically ahead of time.
Why this transition became a template for later similar changes
Ubuntu’s 2006 switch established a pattern other projects and distributions have since followed deliberately when tightening a previously loose compatibility assumption: make the stricter behavior the default first, accept that it will surface a wave of previously-hidden bugs, then let the resulting bug reports drive fixes across the wider ecosystem rather than trying to audit every affected script centrally beforehand. It’s a genuinely different strategy from a purely advisory “please stop relying on bashisms” announcement, and the sheer volume of bugs Ubuntu’s switch actually surfaced is a large part of why later distributions treated Debian’s four-and-a-half-year delay as the more prudent, considerably less disruptive approach genuinely worth following carefully for their own eventual, similar future compatibility transitions much later on down the road.
Related:
- Bash vs. Zsh vs. sh: What Actually Differs Between POSIX Shells
- How to Write Robust, Portable POSIX Shell Scripts
Sources: