set -eBelirli koşullar dışında sıfır olmayan bir çıkış koduyla karşılaşılırsa betiği sonlandırır. Kullanımının tehlikelerini birkaç kelimeyle özetlemek gerekirse: İnsanların yaptıklarını düşündüğü gibi davranmaz.
Benim düşünceme göre, sadece uyumluluk amacıyla varlığını sürdüren tehlikeli bir saldırı olarak kabul edilmelidir. set -eİstisna benzeri kontrol akışını kullanan bir dile hata kodları kullanan bir dilden kabuk açılmıyor açıklamada, bu sadece kötü davranışı taklit etmeye çalışır.
Greg Wooledge'un tehlikeleri hakkında söylenecek çok şey var set -e:
İkinci linkte, sezgisel ve tahmin edilemez davranışların çeşitli örnekleri vardır set -e.
Sezgisel olmayan davranışlarından set -ebazıları (bazıları yukarıdaki wiki bağlantısından alınmış):
-e ayarla
x = 0 olduğu
izin x ++
yankı "x $ x"
Yukarıdakiler, kabuk betiğinin zamanından önce çıkmasına neden olacaktır, çünkü anahtar kelime let x++tarafından letsahte bir değer olarak kabul edilen ve sıfır olmayan bir çıkış koduna dönüştürülen 0 değerini döndürür. set -ebunu fark eder ve sessizce betiği sonlandırır.
-e ayarla
[-d / opt / foo] && echo "Uyarı: foo zaten kurulu. Üzerine yazacak." > Ve 2
echo "Yükleme ..."
Yukarıdakiler beklendiği gibi çalışır, /opt/foozaten varsa bir uyarı yazdırır .
-e ayarla
check_previous_install () {
[-d / opt / foo] && echo "Uyarı: foo zaten kurulu. Üzerine yazacak." > Ve 2
}
check_previous_install
echo "Yükleme ..."
Yukarıdakiler, tek bir çizginin bir işleve yeniden yansıtılmasının tek fark olmasına rağmen, /opt/foomevcut değilse sona erecektir . Bunun nedeni asıl işe yaradığı gerçeği, set -edavranışının özel bir istisnasıdır . Ne zaman a && bdöner sıfırdan farklı, o tarafından göz ardı edilir set -e. Ancak, bu bir fonksiyon olduğu için, fonksiyonun çıkış kodu o komutun çıkış koduna eşittir ve sıfır döndürmeyen fonksiyon komut dosyasını sessizce sonlandırır.
-e ayarla
IFS = $ '\ n' okuma -d '' -r -a config_vars <config
Yukarıdaki config_varsdosya dizisinden okuyacaktır config. Yazarın niyetinde olabileceği gibi config, eksikse bir hatayla sonlanır . Yazar niyetlenmeyebileceğinden, configyeni bir satırda bitmezse sessizce sona erer . Eğer set -eburada kullanılmadı, sonra config_varsyeni bir satırdan sona erdi olsun veya olmasın dosyanın tüm satırları içerecektir.
Sublime Text (ve yeni satırları yanlış işleyen diğer metin editörleri) kullanıcıları, dikkat edin.
-e ayarla
should_audit_user () {
yerel grup grupları = "$ (" $ 1 ") gruplar"
$ gruplar içindeki grup için; yap
eğer ["$ group" = denetim]; sonra 0 döndürün; fi
tamam
1 dönüş
}
should_audit_user "$ user" ise; sonra
logger 'Blah'
fi
Buradaki yazar, bir nedenden ötürü kullanıcının $userolmaması groupsdurumunda , komutun başarısız olacağını ve kullanıcının denetlenmeyen bir görevi yerine getirmesine izin vermek yerine komut dosyasının sonlandırılmasını bekleyebilir . Ancak, bu durumda set -efesih asla geçerli olmaz. Herhangi bir $usersebepten dolayı bulunamazsa, betiği sonlandırmak yerine, should_audit_userişlev set -eetkin değilmiş gibi yanlış verileri döndürür .
Bu, bir ififadenin koşulu kısmından çağrılan tüm işlevler için geçerlidir; ne kadar iç içe olursa olsun, nerede tanımlanmış olursa olsun, set -etekrar içeri girseniz bile . ifHerhangi bir noktada kullanılması set -e, durum bloğu tamamen yürütülene kadar etkisini devre dışı bırakır . Eğer yazar bu engelin farkında değilse ya da bir fonksiyonun çağrılabileceği tüm olası durumlarda tüm çağrı yığınlarını bilmiyorsa, buggy kodu yazacak ve sağladığı yanlış güvenlik duygusu set -een azından kısmen suçlarlar.
Yazar bu eksikliğin tam olarak farkında olsa bile, geçici çözüm, kodun bir yazmadan yazdığı gibi yazılması set -e, bu geçişin faydasızdan daha az etkili olması; yazarın sadece el ile yapılan hata işleme kodlarını, sanki set -eyürürlükte değillermiş gibi yazmakla kalmaz, aynı zamanda set -evar olmadıklarını düşünerek kandırmış olabilir.
Bazı başka dezavantajları set -e:
- Özensiz kodu teşvik eder. Hata işleyicileri, unutulanların hatayı makul bir şekilde rapor etmeleri umuduyla tamamen unutulur. Ancak,
let x++yukarıdaki gibi örneklerle , durum böyle değil. Komut beklenmedik bir şekilde ölürse, genellikle sessizce çalışır, bu hata ayıklamayı engeller. Senaryo ölmezse ve ummasını beklersen (önceki madde işaretine bakınız), o zaman ellerinde daha ince ve sinsi bir böcek vardır.
- İnsanları sahte bir güvenlik hissine yönlendirir. Tekrar
ifkondisyon mermi noktasına bakınız.
- Kabuğun sonlandığı yerler, kabuklar veya kabuk versiyonları arasında tutarlı değildir. Yanlışlıkla bash'ın eski bir sürümünde farklı davranış gösteren bir komut dosyası yazmak,
set -ebu sürümler arasında ince ayar yapılması nedeniyle mümkündür .
set -eçekişmeli bir meseledir ve bazı insanlar çevreyi çevreleyen sorunların farkındayken, bazıları ise tuzakları bilmek aktifken dikkat etmeyi önerir. set -eTüm senaryolarda hata durumlarını yakalamalarını öneren pek çok shell komut dosyası yeniliği vardır , ancak gerçek hayatta bu şekilde çalışmaz.
set -e eğitim yerine geçmez.