set -e
Belirli 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 -e
bazı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 let
sahte 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 -e
bunu 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/foo
zaten 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/foo
mevcut değilse sona erecektir . Bunun nedeni asıl işe yaradığı gerçeği, set -e
davranışının özel bir istisnasıdır . Ne zaman a && b
dö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_vars
dosya dizisinden okuyacaktır config
. Yazarın niyetinde olabileceği gibi config
, eksikse bir hatayla sonlanır . Yazar niyetlenmeyebileceğinden, config
yeni bir satırda bitmezse sessizce sona erer . Eğer set -e
burada kullanılmadı, sonra config_vars
yeni 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 $user
olmaması groups
durumunda , 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 -e
fesih asla geçerli olmaz. Herhangi bir $user
sebepten dolayı bulunamazsa, betiği sonlandırmak yerine, should_audit_user
işlev set -e
etkin değilmiş gibi yanlış verileri döndürür .
Bu, bir if
ifadenin 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 -e
tekrar içeri girseniz bile . if
Herhangi 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 -e
en 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 -e
yürürlükte değillermiş gibi yazmakla kalmaz, aynı zamanda set -e
var 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
if
kondisyon 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 -e
bu 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 -e
Tü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.