What's the problem with Bashisms?

With "Bashism" I mean shell syntax which is only understood by the bash shell and not other shells.

If you write a script which gets executed only in environments where /bin/bash exists, then I think avoiding Bashism is just useless and wasting time, but maybe I am missing something.

What is the benefit of scripting things in a more complicated way, when there is an easier solution if you are allowed to use a feature which is only available in the Bash?

There is a follow-up question: Are there concrete figures on the speed of bash vs dash?

I published my conclusion here: https://github.com/guettli/programming-guidelines/#portable-shell-scripts


First, portability. Nothing wrong if you are sure bash ( and preferably same or newer ) version will be everywhere you use the script. If you're a developer or sysadmin that expects software to be used on Unix-like OS besides Ubuntu, and they may or may not have bash, then bashisms won't be understood by /bin/sh.

Second, POSIX compliance. If you write and submit scripts to be included as part of OS or a project, they often required to be in /bin/sh syntax, which is basically what POSIX standard is. /bin/sh is often preferred for performance reasons, so if you need speed in shell scripts, bashisms and therefore bash maybe something to avoid.

In short, bashisms aren't bad. It really depends on the context for which you write a script. If it's a certainty that bash will be available, and not very outdated, then by all meens use the features - they're there for a reason.


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 [ .. ]