Cara yang tepat untuk mendistribusikan skrip shell


8

Apa cara yang paling tepat untuk mendistribusikan skrip shell, jika perilaku shell dapat dimodifikasi oleh setdan karenanya tidak dapat diprediksi?

Misalnya, rm *.txttidak akan dieksekusi seperti yang diharapkan pada lingkungan di mana set -ftelah dijalankan. Bagaimana saya memastikan bahwa rm *.txtmenghapus semua file teks dalam direktori saat ini di lingkungan apa pun?

Bagaimana saya memastikan bahwa skrip shell akan berjalan seperti yang diharapkan sebelum mendistribusikannya secara umum?


shell_state=$(set +o) ... skrip ...eval "$shell_state"
mikeserv

Anda bisa menjalankan perintah itu di bagian atas skrip itu sendiri, atau memodifikasi #!untuk menentukan opsi shell apa yang Anda inginkan.
HalosGhost

Jawaban:


6

Skrip shell biasanya diperlakukan seolah-olah mereka sama dengan jenis file executable lainnya, seperti binari, skrip Python, skrip Perl, atau skrip jenis apa pun. Mereka memiliki shebang di bagian atas yang mengarahkan kernel untuk menjalankannya melalui shell. Mereka diharapkan dipanggil dengan cara yang sama seperti perintah lainnya.

Dengan demikian, sebuah shell baru dimulai setiap kali script dipanggil, dan pengaturan apa pun seperti yang set -fada di shell yang dijalankan atau dalam instance shell lain dalam sistem tidak relevan.

Tentu saja mungkin bagi pengguna untuk sumber skrip Anda daripada menjalankannya, misalnya seperti ini:

. /path/to/your/script

atau untuk menjalankannya di shell yang memiliki pengaturan non-default seperti ini:

sh -f /path/to/your/script

tetapi itu tidak dianggap sebagai cara normal atau menjalankan skrip Anda, dan pengguna yang melakukannya harus mengharapkan apa pun yang mereka dapatkan sebagai hasilnya.

Perhatikan bahwa ada beberapa skrip yang dimaksudkan untuk dipasok, tidak dieksekusi, karena tujuannya adalah untuk hal-hal seperti mengubah cwd atau mengatur variabel lingkungan yang harus tercermin dalam lingkungan shell sumber, tetapi ini adalah minoritas dan biasanya dilakukan sebagai bagian dari protokol yang disepakati. File-file ini dapat dianggap lebih seperti "plugin" untuk sistem apa pun yang mereka harapkan bersumber, tidak sebanyak skrip independen. Sebagai contoh, file /etc/rc*.ddengan nama yang berakhir .shbersumber dari subsistem skrip startup, tidak dieksekusi, dan didokumentasikan bahwa inilah yang akan terjadi jika Anda menempatkan file dengan nama seperti itu di/etc/rc*.ddan ketika itu selesai itu dilakukan dengan sengaja. Konvensi penamaan file yang dimaksudkan bersumber alih-alih dieksekusi dengan cara ini juga diikuti di tempat lain, tetapi tidak secara universal.

Memang benar bahwa file-file yang dimaksudkan bersumber dengan cara ini harus memperhatikan pengaturan apa yang mungkin ada di lingkungan pemanggil mereka yang mungkin mempengaruhi perilaku shell, tetapi kemudian protokol yang disepakati idealnya menjanjikan lingkungan eksekusi yang dapat diprediksi.


1
zshmemiliki fitur yang memungkinkan untuk mengembalikan opsi ke pengaturan pengetahuan dalam konteks lokal ( emulate -L zsh) yang digunakan secara luas di semua ekstensi yang dikirimkan dengan zsh dan ditulis sebagai kode zsh. Lihat bagaimana sistem penyelesaian bash gagal total jika Anda mengatur beberapa opsi seperti failglob.
Stéphane Chazelas

Beberapa shell membaca file kustomisasi Anda bahkan ketika dipanggil untuk menafsirkan skrip. Itu sebabnya Anda biasanya menggunakan, #! /bin/csh -fbukan #! /bin/cshmisalnya.
Stéphane Chazelas

@ StéphaneChazelas Haha, ya memang. Tentu saja itu bagian dari mengapa menggunakan csh adalah ide yang buruk , bukan? :-) Tapi saya kira zsh juga punya itu, dalam bentuk zshenv. Hati-hati dengan apa yang Anda masukkan zshenvkarena alasan itu!
Celada

@ StéphaneChazelas ngomong-ngomong, ini bukan pertama kalinya Anda mengajari saya sesuatu yang tidak saya ketahui ( emulate -Ldalam hal ini) dengan mengomentari salah satu jawaban saya, dan saya menghargainya.
Celada

Nah, ~/.zshenv(di mana Anda ingin memaksakan pengaturan (umumnya env vars) untuk semua zsh's (interaktif atau tidak) dipanggil dengan nama Anda, dan umumnya tidak digunakan kecuali untuk mengatasi beberapa masalah non-zsh lainnya) terpisah dari ~/.zshrc(interaktif shell kustomisasi), jadi itu, fitur, bukan bug. (Anda dapat menggunakan zsh -f) Bug adalah ketika beberapa shell bash non-interaktif membaca Anda ~/.bashrc(seperti lebih dari ssh dan Anda harus menambahkan kode untuk menjaga terhadap itu), atau beberapa bash interaktif (yang login) tidak membacanya (dan lagi, Anda harus menambahkan kode Anda ~/.bash_profileuntuk mengatasinya).
Stéphane Chazelas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.