I’m wondering if there’s an objectively better bash shebang for most use cases. Options I’ve seen include:
#!/usr/bin/env bash
#!/bin/bash
#!/bin/sh
#!/sh -
I also heard that adding a dash (-) at the end might prevent someone from passing a command to your script. Which shebang is considered best practice and why?
A few notes on the other options:
* #!/bin/sh → Runs in POSIX-compliant mode, not necessarily Bash. Good for portable scripts, but some Bash-specific features won’t work.
-
#!/sh - → Rarely used; the dash is meant to make the shell a login shell, but it’s not needed for most scripts.
Passing a command (like bash -c “…”) is independent of the shebang—don’t rely on the dash to block it.
You might see:
#!/bin/bash
This works if you know the system has Bash installed at /bin/bash.
Slightly faster than env because it doesn’t spawn a new process.
I usually reserve this for controlled environments like my own servers or CI pipelines.
I’ve gone back and forth on this before
. For most scripts, I use:
#!/usr/bin/env bash
env finds the first bash in the user’s PATH, so it’s more portable across systems.
Useful if bash isn’t in /bin (some Linux distros, macOS, or custom environments).
Works well for scripts shared across multiple machines.