Ubuntu-OSX Compatibility: Use #!/bin/sh or #!/bin/bash for POSIX Compliance

bashosxposixshellUbuntu

I know that I can use either as the first line of scripts to invoke the desired shell.

Would #!/bin/sh be recommended if compatibility with all unix systems is an absolute requirement?

In my case the only OS' I care about are Ubuntu (Debian) and OSX.
Given that, could I use #!/bin/bash and be assured it would work on both systems?
Would this also make it easier to use scripts with more modern and clearer syntax for commands? Does using #!/bin/sh also relate to using POSIX ?

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:

#!/usr/bin/env bash

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:

[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"

whereas in traditional shell dialects you'd have to resort to:

test -f "/etc/debian_version" && echo "This is a Debian flavor"

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.