Saya memiliki skrip yang ingin saya jalankan di dua mesin. Kedua mesin ini mendapatkan salinan skrip dari repositori git yang sama. Skrip harus dijalankan dengan penerjemah yang tepat (mis. zsh
).
Sayangnya, keduanya env
dan zsh
tinggal di lokasi yang berbeda di mesin lokal dan jarak jauh:
Mesin jarak jauh
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Mesin lokal
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
Bagaimana saya bisa mengatur Shebang sehingga menjalankan skrip sebagai /path/to/script.sh
selalu menggunakan Zsh
tersedia di PATH
?
Jawaban yang Diterima:
Anda tidak dapat menyelesaikan ini melalui Shebang secara langsung, karena Shebang murni statis. Apa yang dapat Anda lakukan adalah memiliki beberapa »pengganda paling umum« (dari perspektif shell) di Shebang dan jalankan kembali skrip Anda dengan shell yang tepat, jika LCM ini bukan zsh. Dengan kata lain:Minta skrip Anda dieksekusi oleh shell yang ditemukan di semua sistem, uji zsh
-hanya fitur dan jika tes ternyata salah, minta skrip exec
dengan zsh
, di mana tes akan berhasil dan Anda hanya melanjutkan.
Salah satu fitur unik di zsh
, misalnya, adalah adanya $ZSH_VERSION
variabel:
#!/bin/sh -
[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"[email protected]"}
# zsh-specific stuff following here
echo "$ZSH_VERSION"
Dalam kasus sederhana ini, skrip pertama kali dieksekusi oleh /bin/sh
(semua sistem mirip Unix pasca-80-an memahami #!
dan memiliki /bin/sh
, baik Bourne atau POSIX tetapi sintaks kami kompatibel untuk keduanya). Jika $ZSH_VERSION
adalah tidak set, skrip exec
itu sendiri melalui zsh
. Jika $ZSH_VERSION
sudah diatur (resp. skrip sudah dijalankan melalui zsh
), tes ini dilewati begitu saja. Voila.
Ini hanya gagal jika zsh
tidak ada di $PATH
sama sekali.
Sunting: Untuk memastikan, Anda hanya exec
sebuah zsh
di tempat biasa, Anda bisa menggunakan sesuatu seperti
for sh in /bin/zsh
/usr/bin/zsh
/usr/local/bin/zsh; do
[ -x "$sh" ] && exec "$sh" - "$0" ${1+"[email protected]"}
done
Ini dapat menyelamatkan Anda dari exec
secara tidak sengaja 'ing sesuatu di $PATH
Anda yang bukan zsh
Anda harapkan.