0

I typically put a shebang for bash at the top of my shell scripts, e.g.:

#!/usr/bin/bash

However I see many other variants of this, like #!/bin/bash or #!/usr/local/bin/bash etc.

It seems to me these different conventions would result in compatibility or portability issues. If my bash is at another location than someone else's, my script won't work on their machine and vice versa.

If a shell interpreter like bash is apparently not always at the same location, isn't it plain WRONG to explicitly use a hardcoded path in a script?

I understood you can use a somewhat more flexible or less system-dependent approach like this:

#!/usr/bin/env bash

Which results in the (or a?) local version of bash, wherever that may be installed.

Does the latter variant always work? Or is there a better approach that has the highest chance of referring to any system's bash regardless of where it's installed?

RocketNuts
  • 9,958
  • 11
  • 47
  • 88
  • 2
    This might help: [What is the difference between “#!/usr/bin/env bash” and “#!/usr/bin/bash”?](https://stackoverflow.com/q/16365130/3776858) or [Why is #!/usr/bin/env bash superior to #!/bin/bash?](https://stackoverflow.com/q/21612980/3776858) – Cyrus Dec 29 '18 at 17:50
  • @Cyrus I see, thanks. Is `/usr/bin/env` "guaranteed" to exist? Or at least, more so than `/usr/bin/bash` ? Otherwise it would still suffer from the same problem. – RocketNuts Dec 29 '18 at 23:13
  • Just go with #!/usr/bin/env bash . Screwed up systems lose out, but you tried your best, and you're not in the business of unscrewing them anyway. –  Dec 29 '18 at 23:54
  • @Roadowl Unfortunately, using `env` makes the script dependent not only on the system, but on the environment (specifically, the `PATH`) the process gets started with. So the exact same script on the same computer may run under different interpreters depending on how it's launched. – Gordon Davisson Dec 30 '18 at 01:13

1 Answers1

1

I would recommend either "#!/bin/bash" or "#!/usr/bin/bash". On a modern Linux distro, bash should be installed in both places.

Apparently, that isn't true for OpenBSD ... which uses ksh as the default shell. But on an OpenBSD system, you are liable to find that bash isn't installed at all. It is apparently an optional package, and the admin may have not installed it.

So, if you want to maximize portability, use "/bin/sh" and restrict yourself to standard POSIX shell syntax and commands. "/bin/sh" is typically a link to bash or ksh, and runs in POSIX compliant mode.


Other variations:

  • "#!/usr/local/bin/bash" typically won't work on Linux. If it does, it may give you a locally built / modified version of bash.

  • "#!/usr/bin/env bash" should work, with a couple of caveats:

    1. This will give you whatever version of bash is first on the user's command search path (i.e. $PATH).

    2. It is conceivable that the path to env may be different, or that it may not exist. (The env command wasn't in the first version of the POSIX specs.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216