Tengo un script que quiero poder ejecutar en dos máquinas. Estas dos máquinas obtienen copias del script del mismo repositorio de git. El script debe ejecutarse con el intérprete correcto (por ejemplo, zsh
).
Desafortunadamente, ambos env
y zsh
vivir en diferentes ubicaciones en las máquinas locales y remotas:
Máquina remota
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Máquina local
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
¿Cómo puedo configurar Shebang para ejecutar el script como /path/to/script.sh
? siempre usa el Zsh
disponible en PATH
?
Respuesta aceptada:
No puede resolver esto a través de shebang directamente, ya que shebang es puramente estático. Lo que podría hacer es tener algún "multiplicador menos común" (desde una perspectiva de shell) en el shebang y volver a ejecutar su secuencia de comandos con el shell correcto, si este LCM no es zsh. En otras palabras:haga que su script sea ejecutado por un shell que se encuentra en todos los sistemas, pruebe un zsh
-solo función y si la prueba resulta falsa, tenga el script exec
con zsh
, donde la prueba tendrá éxito y usted simplemente continúa.
Una característica única en zsh
, por ejemplo, es la presencia de $ZSH_VERSION
variables:
#!/bin/sh -
[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"[email protected]"}
# zsh-specific stuff following here
echo "$ZSH_VERSION"
En este caso simple, el script se ejecuta primero por /bin/sh
(Todos los sistemas similares a Unix posteriores a los 80 entienden #!
y tener un /bin/sh
, ya sea Bourne o POSIX, pero nuestra sintaxis es compatible con ambos). Si $ZSH_VERSION
es no conjunto, el script exec
's en sí mismo a través de zsh
. Si $ZSH_VERSION
está configurado (resp. el script ya se ejecuta a través de zsh
), la prueba simplemente se salta. Voila.
Esto solo falla si zsh
no está en el $PATH
en absoluto.
Editar: Para asegurarse, solo exec
un zsh
en los lugares habituales, podría usar algo como
for sh in /bin/zsh
/usr/bin/zsh
/usr/local/bin/zsh; do
[ -x "$sh" ] && exec "$sh" - "$0" ${1+"[email protected]"}
done
Esto podría evitar que accidentalmente exec
'ing algo en su $PATH
que no es el zsh
que estás esperando.