Nothing, as such, if you know you're using a Bash-specific feature, and remember to use the #!/bin/bash
hashbang instead of assuming /bin/sh
is Bash.
In Ubuntu (and Debian) "bashisms" in #!/bin/sh
scripts are/were mostly an issue when the default /bin/sh
was changed to Dash instead of Bash as it was earlier (see DashAsBinSh in Ubuntu wiki). All scripts running with /bin/sh
had to be checked for bashisms and fixed to use standard features supported by Dash. The change wasn't about availability of Bash (it's still an Essential
package, so always installed), but about speed: before systemd, the bootup process spawned numerous shell scripts, and changing the default shell to a faster one actually had an impact.
On other systems, /bin/sh
might still be Bash, making it possible to accidentally use Bash-specific features in scripts marked with #!/bin/sh
. They would not work directly in a system where sh
is not Bash. Then there are systems that don't have Bash at all. Embedded systems often only have the Busybox shell. Non-Linux Unixen may not have Bash, though they often do have some version of ksh, which is where many of Bash's features come from. They're not 1:1 compatible, however.
Some of the non-standard features in Bash are very useful (e.g. arrays, substring slices (${var:n:m}
), text replace (${var/foo/bar}
)), so if they make your script easier to write, by all means use Bash.
That said, there are some bashisms that have direct standard equivalents, meaning that there's little or no reason to use the non-standard variant. Some that come to mind:
- the
==
operator in [ .. ]
is non-standard, but equivalent to the standard =
operator
function f { ... }
and f() { ... }
are equivalent in Bash, but the former is non-standard. (It's from ksh, where there's a difference.)
$((--n))
is non-standard, but can be replaced with $((n=n-1))
- In the simple cases
[[ ... ]]
can be replaced with the standard [ .. ]
bash
, why bother at all?