10

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

Eliah Kagan
  • 117,780
guettli
  • 1,777
  • 4
    Long story short: portability. – traducerad Jul 25 '18 at 07:44
  • I vote to close this question as primarily opinion-based. Who says there’s anything wrong with bashisms in the first place? If you don’t need portability to systems without bash, why bother at all? – dessert Jul 25 '18 at 07:55
  • @traducerad protability to what? Is there a system where bash does not exist? AFAIK the bash shell can be installed on all linux environments. I don't care for ms-windows or unix/aix/hp-ux systems. And even on these systems the bash can be installed. – guettli Jul 25 '18 at 07:56
  • 1
    @dessert you understood me "why bother at all?". I see a lot of people wasting time because the want to avoid bashism. I don't get it. The bash is great, it is available. Why not use it? – guettli Jul 25 '18 at 07:58
  • It may also depend on the context; I tend to only use the word "bashism" for usage of bash-specific features in shell scripts that use #! /bin/sh. In other words, for situations where it is incorrectly assumed that bash features will work. In my view, using bash-specific functionality is fine, if the script is explicit about requiring that (i.e. #! /bin/bash or similar). – marcelm Jul 25 '18 at 10:08
  • 6
    @guettli: My router doens't have enough memory to store a kernel, core userland utilities and Bash and it's cheaper and easier to replace Bashisms with whatever Busybox understands for what little I need that router to do. – David Foerster Jul 25 '18 at 12:31
  • @traducerad you say "Long story short: portability". Does a shell script work on my watch? If there is a bash for my watch, then yes. I my environment there is always a bash available, since I do not code for embedded devices. If you are lucky and have bash everywhere you need it, then "portability" .... – guettli Aug 30 '18 at 09:39
  • @guettli The question is not about whether an embedded device is able to run a shell script. But rather whether it is able to run bash scripts. There are many types of shells. A bash script won't necessarily be understood by eg tcsh: http://joelinoff.com/blog/?page_id=235 – traducerad Aug 30 '18 at 18:50
  • @traducerad once upon a time I heard the term "dependency management". I am unsure what this really means. I don't think that you can somehow magically create a dependency between a RPM/DPKG an the bash. With other words: bash is available before the script gets executed. Would be great if this would be possible. – guettli Aug 31 '18 at 07:21
  • @traducerad about Portability: https://github.com/guettli/deadends-of-it/blob/master/README.md#portability – guettli Jul 04 '19 at 13:04

2 Answers2

17

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.

Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • OP seems to premise bashisms should best be avoided at all – maybe write something about that too? ;P – dessert Jul 25 '18 at 08:01
  • @dessert T_T I'm typing on phone. – Sergiy Kolodyazhnyy Jul 25 '18 at 08:05
  • Honestly, how likely are you to encounter a Unix-like system anywhere today without Bash available? – leftaroundabout Jul 25 '18 at 08:27
  • 5
    @leftaroundabout: Plenty of specialized embedded systems ship without bash. – hmakholm left over Monica Jul 25 '18 at 09:02
  • @leftaroundabout you talk about "specialized embedded systems". I care for them like I care for ms-windows or android (in the context of this question): Not at all. Please read the question carefully. "If you write a script which gets executed only in environments where /bin/bash exists ...". – guettli Jul 25 '18 at 11:19
  • It's not necessarily about Bash not being available, but rather about it not being installed. BSDs don't have Bash installed by default, for example. – Daniel Gray Feb 04 '20 at 12:14
13

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 [ .. ]
ilkkachu
  • 1,837