If my goal is to write a script for POSIX compatible shells, scripts that I would begin with #!/bin/sh, how permissible is this [[
syntax.
Not at all. Many modern Linux-based systems use dash
as /bin/sh
by default, which is fully POSIX-compliant and no more, and so [[
will not work. This includes every recent Debian and Ubuntu release, and their derivatives, as well as many other distributions. Historically these systems commonly used Bash there instead, and deliberately switched to improve performance.
Many other systems, including most of the BSDs and most commercial Unices, don't support [[
either and never have: their sh
is POSIX-only, or its extensions don't include the [[
syntax. OpenBSD's sh
does support a version of [[
, which is slightly different than Bash's; I don't know of any others that do, although they may exist. Otherwise, it's only systems that use Bash as /bin/sh
(or less often zsh
, or even less often some others) where [[
will work in something declared to be a sh
script.
On the other hand, the large majority of systems have Bash installed in practice, and just making your script explicitly be run with bash
will suffice for all of them. Bash's sh
-emulation mode has always been broken anyway.
Since you're relying on Bash features, I can't see any reason at all you'd want to declare it as a sh
script: just say #!/bin/bash
and be done, using [[
as much as you want — or even better, to the total exclusion of [
. If you instead want maximum portability, use [
or test
and POSIX sh
1, and write carefully.
1Note that some of the commercial Unices have, or have had, non-POSIX sh
as /bin/sh
; to work uniformly on those you'll need to run the scripts with the full path to the system's POSIX sh
.
Since back-ticks are often used, it makes sense to teach this syntactic construct.
Of course, $()
style command substitution should be emphasized as the default style (and standard conforming construct).
Why are back-ticks still popular? Because they save one character in typing, and they are arguably less heavy on the eye.
Best Answer
For starters, if you can make the assumption that Bash is preinstalled (which, to my knowledge is the case on all the systems you list), use the following hashbang to be compatible:
this invokes whatever
bash
happens to be configured, no matter whether it's in/bin
or/usr/local/bin
.While on most systems across a wide range (including AIX, Solaris, several BSD flavors),
bash
ended up in different locations,env
always ended up in/usr/bin/env
. The trick, however, is not mine but from the author of the Bash Cookbook.Anyway, yes Bash would allow you to use some "modern" features that make your life easier.
For example the double brackets:
whereas in traditional shell dialects you'd have to resort to:
but the best about the double brackets is that they allow regular expressions for matching. The Bash Hackers Wiki will give you many tricks in that direction.
You can also use quite convenient expressions like
$((2**10))
or other arithmetic expressions inline with the$((expression))
syntax.Using backticks for subshells is fine, albeit a bit outdated. But the nesting capabilities of
$(command ...)
invocations are way more convenient as you won't have to escape many things at different subshell levels.These are but a few things Bash gives you over the traditional common POSIX
sh
syntax.But if you want more power on the shell (not just in scripts), also have a look at
zsh
.