Pertanyaan ini muncul di kuis pra-wawancara dan itu membuat saya gila. Adakah yang bisa menjawab ini dan menenangkanku? Kuis tidak memiliki referensi ke shell tertentu tetapi deskripsi pekerjaan adalah untuk sa unix. sekali lagi pertanyaannya hanyalah ...
Apa yang dilakukan 'set -e', dan mengapa itu dianggap berbahaya?
Jawaban:
set -e
menyebabkan shell keluar jika subkomand atau pipa mengembalikan status tidak nol.Jawaban pewawancara yang mungkin dicari adalah:
Dari http://www.debian.org/doc/debian-policy/ch-opersys.html 9.3.2 -
Ini adalah pertanyaan yang valid dari sudut pandang pewawancara karena ia mengukur seorang kandidat yang memiliki pengetahuan tentang scripting dan otomatisasi tingkat server
sumber
Dari
bash(1)
:Sayangnya saya tidak cukup kreatif untuk berpikir mengapa itu akan berbahaya, selain dari "sisa skrip tidak akan dieksekusi" atau "itu mungkin mungkin menutupi masalah nyata".
sumber
set
! Saya selalu berakhir dibuiltin(1)
. Terima kasih.set
itu harus ditemukanman 1 bash
?? dan bagaimana orang dapat menemukan-e
opsi untukset
kata kunci di halaman manual yang sangat besar? Anda tidak bisa hanya/-e
mencari di sinihelp set
Perlu dicatat bahwa
set -e
dapat dinyalakan dan dimatikan untuk berbagai bagian naskah. Tidak harus aktif untuk eksekusi seluruh skrip. Itu bahkan bisa diaktifkan secara kondisional. Yang mengatakan, saya tidak pernah menggunakannya karena saya melakukan penanganan kesalahan saya sendiri (atau tidak).Juga patut dicatat adalah ini dari bagian halaman Bash pada
trap
perintah yang juga menjelaskan bagaimanaset -e
fungsi dalam keadaan tertentu.Jadi ada beberapa kondisi di mana status bukan nol tidak akan menyebabkan keluar.
Saya pikir bahayanya adalah tidak memahami kapan harus
set -e
bermain dan kapan tidak dan mengandalkannya dengan salah di bawah beberapa asumsi yang tidak valid.Silakan juga lihat BashFAQ / 105 Mengapa set -e (atau set -o errexit, atau trap ERR) tidak melakukan apa yang saya harapkan?
sumber
Ingatlah ini adalah kuis untuk wawancara kerja. Pertanyaan-pertanyaan mungkin telah ditulis oleh staf saat ini, dan mereka mungkin salah. Ini tidak selalu buruk, dan semua orang membuat kesalahan, dan pertanyaan wawancara sering duduk di sudut yang gelap tanpa ulasan, dan hanya keluar selama wawancara.
Sangat mungkin bahwa 'set -e' tidak melakukan apa pun yang kami anggap "berbahaya". Tetapi penulis pertanyaan itu mungkin secara keliru percaya bahwa 'set-e' berbahaya, karena ketidaktahuan atau bias mereka sendiri. Mungkin mereka menulis skrip buggy shell, bomnya mengerikan, dan mereka keliru mengira bahwa 'set -e' yang harus disalahkan, padahal sebenarnya mereka lalai menulis pengecekan kesalahan yang tepat.
Saya telah berpartisipasi dalam mungkin 40 wawancara kerja selama 2 tahun terakhir, dan pewawancara kadang-kadang mengajukan pertanyaan yang salah, atau memiliki jawaban yang salah.
Atau mungkin itu pertanyaan jebakan, yang akan timpang, tetapi tidak sepenuhnya tak terduga.
Atau mungkin ini penjelasan yang bagus: http://www.mail-archive.com/[email protected]/msg473314.html
sumber
set -e
memberitahu bash, dalam sebuah skrip, untuk keluar kapan pun sesuatu mengembalikan nilai pengembalian yang tidak nol.Saya bisa melihat bagaimana itu akan mengganggu, dan buggy, tidak yakin tentang berbahaya, kecuali jika Anda telah membuka izin pada sesuatu, dan sebelum Anda dapat membatasi mereka lagi, skrip Anda mati.
sumber
set -e
, pada kenyataannya, bagi saya itu berbicara tentang malas untuk mengabaikan memeriksa kesalahan dalam skrip Anda ... jadi ingatlah, dengan majikan ini, juga ... jika mereka menggunakannya banyak, seperti apa skrip mereka, yang pasti harus Anda pertahankan ...set -e
menghentikan skrip jika kode keluar yang bukan nol ditemukan, kecuali dalam kondisi tertentu. Untuk meringkas bahaya penggunaannya dalam beberapa kata: itu tidak berperilaku seperti yang orang pikirkan.Menurut pendapat saya, itu harus dianggap sebagai peretasan berbahaya yang terus ada untuk tujuan kompatibilitas saja. The
set -e
pernyataan tidak berubah shell dari bahasa yang menggunakan kode kesalahan ke dalam bahasa yang menggunakan aliran kontrol pengecualian-seperti, itu hanya buruk mencoba untuk meniru perilaku itu.Greg Wooledge banyak bicara tentang bahaya
set -e
:set -e
)Pada tautan kedua, ada berbagai contoh perilaku tidak intuitif dan tidak terduga
set -e
.Beberapa contoh perilaku tidak intuitif
set -e
(beberapa diambil dari tautan wiki di atas):let x++
mengembalikan 0, yang diperlakukan olehlet
kata kunci sebagai nilai palsu dan berubah menjadi kode keluar yang tidak nol.set -e
pemberitahuan ini, dan diam-diam mengakhiri skrip.Di atas berfungsi seperti yang diharapkan, mencetak peringatan jika
/opt/foo
sudah ada.Di atas, meskipun satu-satunya perbedaan adalah bahwa satu baris telah di refactored menjadi suatu fungsi, akan berakhir jika
/opt/foo
tidak ada. Ini karena fakta bahwa itu bekerja pada awalnya adalah pengecualian khusus untukset -e
perilaku. Saata && b
mengembalikan nol, diabaikan olehset -e
. Namun, sekarang karena fungsinya, kode keluar dari fungsi sama dengan kode keluar dari perintah itu, dan fungsi yang mengembalikan bukan nol akan secara diam-diam menghentikan skrip.Di atas akan membaca array
config_vars
dari fileconfig
. Seperti yang mungkin dimaksudkan oleh penulis, itu berakhir dengan kesalahan jikaconfig
hilang. Karena penulis mungkin tidak bermaksud, itu diam-diam berakhir jikaconfig
tidak berakhir pada baris baru. Jikaset -e
tidak digunakan di sini, makaconfig_vars
akan berisi semua baris file apakah itu berakhir pada baris baru atau tidak.Pengguna Teks Sublime (dan editor teks lainnya yang menangani baris baru secara salah), berhati-hatilah.
Penulis di sini mungkin secara wajar berharap bahwa jika karena alasan tertentu pengguna
$user
tidak ada, makagroups
perintah akan gagal dan skrip akan berhenti alih-alih membiarkan pengguna melakukan beberapa tugas tanpa diaudit. Namun, dalam hal iniset -e
pemutusan hubungan kerja tidak pernah berlaku. Jika$user
tidak dapat ditemukan karena alasan tertentu, alih-alih menghentikan skrip,should_audit_user
fungsi hanya akan mengembalikan data yang salah seolah-olahset -e
tidak berlaku.Ini berlaku untuk fungsi apa pun yang dipanggil dari bagian kondisi
if
pernyataan, tidak peduli seberapa dalam bersarang, di mana pun didefinisikan, tidak peduli bahkan jika Anda menjalankannyaset -e
lagi. Penggunaanif
pada titik mana pun sepenuhnya menonaktifkan efekset -e
sampai blok kondisi sepenuhnya dieksekusi. Jika penulis tidak mengetahui jebakan ini, atau tidak tahu seluruh tumpukan panggilan mereka dalam semua situasi yang memungkinkan di mana suatu fungsi dapat dipanggil, maka mereka akan menulis kode kereta dan rasa aman palsu yang diberikan olehset -e
akan setidaknya sebagian untuk menyalahkan.Bahkan jika penulis sepenuhnya menyadari jebakan ini, solusinya adalah menulis kode dengan cara yang sama seperti orang akan menulisnya tanpa
set -e
, secara efektif membuat pergantian yang kurang dari berguna; tidak hanya penulis harus menulis kode penanganan kesalahan manual seolah-olahset -e
tidak berlaku, tetapi kehadiranset -e
mungkin menipu mereka untuk berpikir bahwa mereka tidak perlu melakukannya.Beberapa kelemahan lebih lanjut dari
set -e
:let x++
atas, ini tidak terjadi. Jika skrip mati secara tak terduga, biasanya diam-diam, yang menghambat debugging. Jika skrip tidak mati dan Anda mengharapkannya (lihat poin sebelumnya), maka Anda memiliki bug yang lebih halus dan berbahaya di tangan Anda.if
titik peluru -kondisi.set -e
tweak antara versi tersebut.set -e
adalah masalah yang diperdebatkan, dan beberapa orang menyadari masalah di sekitarnya yang merekomendasikannya, sementara yang lain hanya merekomendasikan untuk berhati-hati saat aktif untuk mengetahui perangkapnya. Ada banyak pemula skrip shell yang merekomendasikanset -e
semua skrip sebagai catch-all untuk kondisi kesalahan, tetapi dalam kehidupan nyata itu tidak bekerja seperti itu.set -e
bukan pengganti untuk pendidikan.sumber
Saya akan mengatakan itu berbahaya karena Anda tidak mengontrol lagi alur skrip Anda. Skrip dapat mengakhiri selama salah satu perintah yang dipanggil skrip mengembalikan nol. Jadi yang harus Anda lakukan adalah melakukan sesuatu yang mengubah perilaku atau output dari salah satu komponen, dan Anda bisa mengakhiri skrip utama. Ini mungkin lebih dari masalah gaya, tetapi pasti memiliki konsekuensi. Bagaimana jika skrip utama Anda seharusnya menetapkan beberapa bendera, dan bukan karena itu diakhiri lebih awal? Anda akhirnya akan menyalahkan seluruh sistem jika mengasumsikan bahwa bendera tersebut seharusnya ada di sana, atau bekerja dengan nilai default atau nilai lama yang tidak terduga.
sumber
Sebagai contoh jawaban @ Marcin yang lebih kongkrit yang secara pribadi telah menggigit saya, bayangkan ada suatu
rm foo/bar.txt
baris di skrip Anda. Biasanya bukan masalah besar jikafoo/bar.txt
sebenarnya tidak ada. Namun denganset -e
hadir sekarang skrip Anda akan berakhir lebih awal di sana! Ups.sumber