ERR ve EXIT tuzakları ile birlikte set -e
( errexit
), set -u
( nounset
) kullanırken bazı garip davranışlar gözlemliyorum . İlgili gözüküyorlar, bu yüzden onları bir soruya koymak mantıklı görünüyor.
1) set -u
ERR tuzaklarını tetiklemez
Kod:
#!/bin/bash trap 'echo "ERR (rc: $?)"' ERR set -u echo ${UNSET_VAR}
- Beklenen: ERR tuzağı çağrılıyor, RC! = 0
- Fiili: ERR tuzağı olduğu değil RC == 1 olarak adlandırılan
- Not:
set -e
sonucu değiştirmez
2) set -eu
Bir EXIT tuzağında çıkış kodunu kullanmak 1 yerine 0
Kod:
#!/bin/bash trap 'echo "EXIT (rc: $?)"' EXIT set -eu echo ${UNSET_VAR}
- Beklenen: EXIT tuzağı aranıyor, RC == 1
- Gerçek: EXIT tuzağı denir, RC == 0
- Not: Kullanırken
set +e
, RC == 1. Başka bir komut bir hata attığında, EXIT tuzağı uygun RC'yi döndürür. - Düzenleme: Bu konuda, SO'nun kullanılan Bash sürümüyle ilgili olabileceğini düşündüren ilginç bir yorum içeren bir SO yazısı var . Bu pasajı Bash 4.3.11 ile test etmek bir RC = 1 olur, bu yüzden daha iyidir. Maalesef Bash'in (3.2.51'den) tüm ana bilgisayarlarda yükseltilmesi şu anda mümkün değil, bu yüzden başka bir çözüm bulmalıyız.
Bu davranışlardan herhangi birini açıklayan var mı?
Bu konuların araştırılması çok başarılı olmadı, bu, Bash ayarları ve tuzakları üzerindeki yayınların sayısının verilmesi şaşırtıcıydı. Yine de bir forum konusu var , ancak sonuç oldukça tatmin edici değil.
set -e
ve set -u
her ikisi de özel olarak yazılmış bir kabuğunu öldürmek için tasarlanmıştır . Bunları, uygulamalarını tetikleyebilecek koşullarda kullanmak , komut dosyası yazılan bir kabuğu öldürür . Hiçbir haricinde bu kaçış yoktur değil bunun yerine bunları kullanmak ve testin bir kod sırayla uyguladığınızda bu koşullar için. Yani, temel olarak, iyi bir kabuk kodu yazabilir veya kullanabilirsiniz set -eu
.
-u
ERR tuzağını tetiklemeyeceğine dair yeterli bilgi bulamadığım için her ikisini de arıyorum (bu bir hata, bu yüzden tuzağı tetiklememeli) veya hata kodu 1 yerine 0'dır. İkincisi daha sonraki sürümde zaten düzeltilmiş olan bir hata gibi görünüyor, bu yüzden. Ancak, kabuk değerlendirmedeki hataların (parametre genişlemesi) ve komutlardaki gerçek hataların iki farklı şey gibi göründüğünü anlamadıysanız, ilk bölümün anlaşılması oldukça zordur. Çözüm için, önerdiğiniz gibi, artık -eu
gerektiğinde manuel olarak kontrol etmekten kaçınmaya çalışıyorum .
(set -u; : $UNSET_VAR)
. Bu tür şeyler de iyi olabilir - &&
ara sıra çok şey düşürebilirsiniz : (set -e; mkdir dir; cd dir; touch dirfile)
sürüklenmemi yakalarsanız. Sadece bunlar kontrol edilen bağlamlardır - onları global seçenek olarak ayarladığınızda kontrolü kaybedersiniz ve kontrol edilirsiniz. Yine de, genellikle daha verimli çözümler vardır.
bash
standarttan ayrıldı ve alt kabuklara tuzaklar koymaya başladım. Tuzağın geri döndüğü andan itibaren aynı ortamda yürütülmesi gerekiyordu, ancakbash
bunu bir süredir yapmadı.