Ho uno script che voglio essere in grado di eseguire su due macchine. Queste due macchine ottengono copie dello script dallo stesso repository git. Lo script deve essere eseguito con l'interprete corretto (ad es. zsh
).
Sfortunatamente, entrambi env
e zsh
vivono in luoghi diversi nelle macchine locali e remote:
Macchina remota
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Macchina locale
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
Come posso impostare lo shebang in modo che esegua lo script come /path/to/script.sh
usa sempre Zsh
disponibile in PATH
?
Risposta accettata:
Non puoi risolverlo direttamente tramite shebang, poiché shebang è puramente statico. Quello che potresti fare è avere un "moltiplicatore meno comune" (dal punto di vista della shell) nello shebang e rieseguire il tuo script con la shell giusta, se questo LCM non è zsh. In altre parole:fai eseguire il tuo script da una shell trovata su tutti i sistemi, prova a zsh
-solo funzionalità e se il test risulta falso, avere lo script exec
con zsh
, dove il test avrà esito positivo e tu continuerai.
Una caratteristica unica in zsh
, ad esempio, è la presenza del $ZSH_VERSION
variabile:
#!/bin/sh -
[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"[email protected]"}
# zsh-specific stuff following here
echo "$ZSH_VERSION"
In questo semplice caso, lo script viene prima eseguito da /bin/sh
(tutti i sistemi simili a Unix successivi agli anni '80 comprendono #!
e avere un /bin/sh
, Bourne o POSIX ma la nostra sintassi è compatibile con entrambi). Se $ZSH_VERSION
è non set, lo script exec
's stesso tramite zsh
. Se $ZSH_VERSION
è impostato (risp. lo script è già eseguito tramite zsh
), il test viene semplicemente saltato. Voilà.
Questo fallisce solo se zsh
non è nel $PATH
affatto.
Modifica: Per essere sicuro, devi solo exec
un zsh
nei soliti posti, potresti usare qualcosa come
for sh in /bin/zsh
/usr/bin/zsh
/usr/local/bin/zsh; do
[ -x "$sh" ] && exec "$sh" - "$0" ${1+"[email protected]"}
done
Questo potrebbe salvarti da exec
accidentalmente qualcosa nel tuo $PATH
che non è il zsh
ti aspetti.