I have a script that I want to be able to run in two machines. These two machines get copies of the script from the same git repository. The script needs to run with the right interpreter (e.g. zsh
).
Unfortunately, both env
and zsh
live in different locations in the local and remote machines:
Remote machine
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Local machine
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
How can I set up the shebang so that running the script as /path/to/script.sh
always uses the Zsh
available in PATH
?
Best Answer
You cannot solve this through shebang directly, since shebang is purely static. What you could do is having some »least common multiplier« (from a shell perspective) in the shebang and re-execute your script with the right shell, if this LCM isn't zsh. In other words: Have your script executed by a shell found on all systems, test for a
zsh
-only feature and if the test turns out false, have the scriptexec
withzsh
, where the test will succeed and you just continue.One unique feature in
zsh
, for example, is the presence of the$ZSH_VERSION
variable:In this simple case, the script is first executed by
/bin/sh
(all post-80s Unix-like systems understand#!
and have a/bin/sh
, either Bourne or POSIX but our syntax is compatible to both). If$ZSH_VERSION
is not set, the scriptexec
's itself throughzsh
. If$ZSH_VERSION
is set (resp. the script already is run throughzsh
), the test is simply skipped. Voilà.This only fails if
zsh
isn't in the$PATH
at all.Edit: To make sure, you only
exec
azsh
in the usual places, you could use something likeThis could save you from accidentally
exec
'ing something in your$PATH
which is not thezsh
you're expecting.