3

I'm looking to share a script with someone but am not sure which is preferred on MacOS. Which is best supported?

This?

#!/bin/sh
echo "Here goes my simple script that changes some settings."
# ... do some stuff

Or this?

#!/bin/bash
echo "Here goes my simple script that changes some settings."
# ... do some stuff
terryoboy
  • 136
  • 2
  • 12
  • 2
    It's not so much a matter of what is *preferred*, but what will *work*. The shebang doesn't specify which version of a shell is required. Given that you are asking, you probably aren't aware that `/bin/bash` on a macOS machine is likely much older (version 3.2) than the version of `bash` you are accustomed to using (4.2 or newer). So the question is: which shell does your script *need* to be run? – chepner Oct 21 '19 at 18:57
  • 3
    `/bin/sh` usually means that your script is POSIX-compliant and can be run without modification using any POSIX-compliant shell (`dash`, `ash`, `bash`, `zsh` in compatibility mode, etc). `/bin/bash` says you need `bash`, but doesn't say which version of `bash` is required. – chepner Oct 21 '19 at 18:58
  • 1
    `#!/usr/bin/env bash` is more appropriate if you want to use a copy of bash newer-than-the-OS-provided version, since it'll look up the location in the `PATH`. And, of course, you'll want an explicit version check; something like `case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0+ needed" >&2; exit 1;; esac` – Charles Duffy Oct 21 '19 at 19:46
  • 1
    I think it's answerable, because the answer is that no matter *what* the script writer supplies, it isn't necessarily useful to whoever will *run* the script. I don't like `env` because it's telling the user they can use whatever their preferred `bash` is, and the writer isn't in any position to determine if that's appropriate for the script. – chepner Oct 21 '19 at 20:15
  • @CharlesDuffy why would you downvote for that reason? That's like saying I should have known the answer to my own question. – terryoboy Oct 21 '19 at 21:20
  • 2
    BTW, https://mywiki.wooledge.org/BashGuide/Practices#Choose_Your_Shell is directly on-topic; see the *Always use the correct shebang* bullet point therein, as well as the guidance around when to consider using `sh` rather than bash above that point. – Charles Duffy Oct 21 '19 at 21:27

2 Answers2

9

You should choose a shebang corresponding to the shell dialect/language that the script is written in.

  • If you write for POSIX sh, use #!/bin/sh

  • If you write for Zsh, use #!/usr/bin/env zsh

  • If you write for Fish, use #!/usr/bin/env fish

  • If you write for Bash use #!/usr/bin/env bash* (if you don't know, this is probably it)

sh is to bash roughly what C is to C++, and you should be aware of which one you want to use. For more information, see Difference between sh and bash and Why does my bash code fail when I run it with sh?


* Using env this way is equivalent to #!/bin/bash, but also allows the user to install a newer version of Bash. People on macOS in particular do that because the OS ships with an outdated version.

that other guy
  • 116,971
  • 11
  • 170
  • 194
-2

It doesn't really matter: it's up to the person using the script to make sure the shebang selects the correct interpreter on their machine, so whatever you provide is subject to change on the receiving end.

All you can do is document what the requirements to execute your script are. (For example, "Requires bash 4.2 or later".) You can omit the shebang entirely, since you are relying on the user to know where the required interpreter is anyway.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you. That makes sense and I think this is *the* answer... So would using `/bin/sh` probably be the safest? – terryoboy Oct 21 '19 at 19:02
  • 2
    Only if you don't use any `bash` extensions in your script. It's the content of the script that matters, and the shebang must reflect that. (No matter what you put, the user may need to change it. Maybe you use some feature that requires `bash` 4 or later, but `/bin/bash` is version 3.2 on macOS. The user will have to install their own newer version of `bash`, and change the shebang to reflect where they installed it. You, as the script author, don't know and don't care where the appropriate interpreter lives.) – chepner Oct 21 '19 at 19:09
  • 1
    If you omit the shebang, the script will still run but now it's harder to predict which interpreter it will run with. I don't agree that the user should routinely edit every script to set the shebang, but if that's the goal you can use `#!/bin/echo Please edit this script and set the correct path to bash` or whatever. – that other guy Oct 21 '19 at 21:38