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.