J'ai un script que je veux pouvoir exécuter sur deux machines. Ces deux machines obtiennent des copies du script à partir du même référentiel git. Le script doit s'exécuter avec le bon interpréteur (par exemple, zsh
).
Malheureusement, les deux env
et zsh
vivent à différents endroits sur les machines locales et distantes :
Appareil distant
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Ordinateur local
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
Comment puis-je configurer le shebang pour exécuter le script en tant que /path/to/script.sh
utilise toujours le Zsh
disponible dans PATH
?
Réponse acceptée :
Vous ne pouvez pas résoudre ce problème directement à travers le shebang, car le shebang est purement statique. Ce que vous pourriez faire, c'est avoir un "multiplicateur le moins commun" (du point de vue du shell) dans le shebang et ré-exécuter votre script avec le bon shell, si ce LCM n'est pas zsh. En d'autres termes :faites exécuter votre script par un shell présent sur tous les systèmes, testez un zsh
-seule fonctionnalité et si le test s'avère faux, avoir le script exec
avec zsh
, où le test réussira et vous continuerez simplement.
Une fonctionnalité unique dans zsh
, par exemple, est la présence du $ZSH_VERSION
variables :
#!/bin/sh -
[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"[email protected]"}
# zsh-specific stuff following here
echo "$ZSH_VERSION"
Dans ce cas simple, le script est d'abord exécuté par /bin/sh
(tous les systèmes de type Unix postérieurs aux années 80 comprennent #!
et avoir un /bin/sh
, Bourne ou POSIX mais notre syntaxe est compatible avec les deux). Si $ZSH_VERSION
n'est pas set, le script exec
's lui-même via zsh
. Si $ZSH_VERSION
est défini (resp. le script est déjà exécuté via zsh
), le test est simplement sauté. Voilà.
Cela n'échoue que si zsh
n'est pas dans le $PATH
du tout.
Modifier : Pour vous en assurer, vous ne faites que exec
un zsh
aux endroits habituels, vous pouvez utiliser quelque chose comme
for sh in /bin/zsh
/usr/bin/zsh
/usr/local/bin/zsh; do
[ -x "$sh" ] && exec "$sh" - "$0" ${1+"[email protected]"}
done
Cela pourrait vous éviter accidentellement exec
‘ing quelque chose dans votre $PATH
qui n'est pas le zsh
vous attendez.