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.