Desen neden “komut || doğru ”kullanışlı?


79

Şu anda Debian paketlerini inceliyorum ve bazı kod örneklerini okudum. Ve her satırda, örneğin, postinstsenaryo bir kalıptır.

some command || true
another command || true

Eğer bazı komutlar başarısız olursa, o zaman satır doğru döner ancak bunun programın çıktısını nasıl etkilediğini göremiyorum.


5
Bilginize, ||:bu (yazma başka deyimsel yoludur :işaret yerleşik tabloda başka giriş olmanın trueancak - garantili bile geri Bourne bir yerleşiğini olmak; POSIX sh için, söz konusu trueaynı şekilde bir yerleşik olması sağlanır - bu yüzden bu kadar uzaktan bile modern zamanlarda verimden daha fazla netlik).
Charles Duffy

Yanıtlar:


151

Bu şablonun nedeni, Debian paketlerindeki koruyucu komut dosyalarının başlama eğilimi göstermesidir set -e; bu, herhangi bir komutun (kesinlikle konuşma, boru hattı, liste veya bileşik komut) sıfır olmayan bir durumdan çıkar çıkmaz kabuğun çıkmasına neden olur. Bu, hataların birikmemesini sağlar: bir şeyler ters giderse, komut dosyası iptal edilir.

Koddaki bir komutun başarısız olmasına izin verilen durumlarda, ekleme || true, sonuçta elde edilen bileşik komutunun her zaman sıfır durumuyla çıkmasını sağlar, böylece komut dosyası iptal edilmez. Örneğin, bir dizini kaldırmak çok önemli bir hata olmamalıdır (bir paketin çıkartılmasını engellemek); bu yüzden kullanırdık

rmdir ... || true

çünkü rmdirhataları görmezden gelmesini söyleme seçeneğine sahip değil.


4
Buna set -ehiç gerek kalmadan || true, bağlamı sağlamanın önemli olduğunu düşündüm. GÜÇ ile ilgili garip şeyler fark ederseniz, sizi hataların ( reportbug) dosyalamasını şiddetle tavsiye ederim !
Stephen Kitt

16
@MichaelFelt, aslında set -esadece "Debian kongre" değil, her zaman kullanması gereken iyi bir programlama şeklidir. Görmek. örneğin davidpashley.com/articles/writing-robust-shell-scripts
kay

2
Buradaki soruya göre - neden || trueset setini kullanın -e olası bağlam ve muhtemelen en yaygın olanıdır. Bu cevaba boyun eğiyorum! Kelimenin tam anlamıyla, çıkış durumu alakasız sayılırsa faydalıdır VE (bağlantı ekledikçe) çıkış durumunu komut dosyası denetimimin bir parçası olarak kullanmıyorum. Yardımcı programı (in set -e) görüyorum, ancak makalenin yaptığı kadar ileri gitmeyecek ve "Yazdığınız her komut dosyası en üste set -e eklemeli" der. Bir programlama tarzıdır. "HER ZAMAN | Her biri" kendi tuzakları setini içerir - aka - absolute re: wild-kart çözümleri ALWAYSsonunda geri tepecektir aka - serbest sürüş yok.
Michael

1
@Kay Bu şu anda popüler bir bakış açısı ancak sonuçta betiğin taşınabilirliğini sınırlandıran sayısız varsayımla birleştirildi. set -eDavranışta tarihsel tutarsızlıklar var . Tek hedefleriniz bashve yaşayan diğer nispeten yakın mermiler ise, sizin için önemli olmayabilir /bin/sh, ancak eski mermileri / sistemleri desteklemek istediğinizde durum daha da farklı olacaktır.
mtraceur

2
@StephenKitt Elbette bir şey. Sven Mascheck'in farklı mermilerin set -edavranışlarını belgeleyen çok kapsamlı bir sayfa var , ancak bu sayfa günümüzde ilgisini çeken birçok tarihi / eski mermiyi de belgeliyor. Ayrıca, daha dar ve modern bir odaklanmaya sahip bu iki sayfa da var ("set -e" için arama yapın): "lintsh" sayfası , autoconf'un taşınabilir kabuk dokümantasyonu ->
Builtins'in

32

Sadece çalışan programın çıktısını etkilemese de, arayanın her şey yolundaymış gibi devam etmesine izin verir aka, gelecekteki mantığı etkiler.

Rephrased: önceki komutun hata durumunu maskeler .

michael@x071:[/usr/sbin]cat /tmp/false.sh
#!/bin/sh
false

michael@x071:[/usr/sbin]cat /tmp/true.sh 
#!/bin/sh
false || true

michael@x071:[/usr/sbin]sh /tmp/false.sh; echo $?
1
michael@x071:[/usr/sbin]sh /tmp/true.sh; echo $? 
0

6
Bu doğru, ancak bir komutun çıkış durumunu maskelemenin neden yararlı olduğunu cevaplamıyor.
moopet

4
set -e, betiğin sıfır olmayan bir dönüşle anında sonlandırılacağı anlamına gelir. Bu lokalize noktada, bunun olmasını istemeyebilirsiniz!
rackandboneman

Ben basit bir insanım - ve benim için hata durumunu maskelemenin tek sebebi "şekilde" olmasıdır. set -e daha önce umursamadıysanız, "şekilde" herhangi bir hata yapar. Tartışmayı seviyorum, çünkü komut dosyalarımda hata ayıklamama ve bir hataya cevap vermek için ek mantık yazmama yardımcı olacak güzel bir yol olarak görüyorum (örneğin, || print - "xxx burada sıfır olmayan bir dosya var". kabuk işlevi 'ölümcül' ve ben "şey || ölümcül" mutsuz bana ". imho bir betiğin başarısız bir durum bildirmesi veya umursamamanız gerekir. -e plus || true, maskeleme hataları. İstediğim buysa - tamam, değilse, hatalarımı özlüyorum
Michael

kendime sormam gereken şu: is || true - bir kodlama koltuk değneği (bir hatayı aşmak / geçmek için tembel bir yolla şimdi uğraşmak istemiyorum; bir hata ayıklama aracı (-e ama hayır || doğru değil) ya da sadece birinin kodlama uygulamasının ne olduğu hakkında dogması. - Ben bunu bir özellik olarak görüyorum - potansiyel fayda ile. Hepsini iyileştirmek için onu sihirli bir değnek olarak görmüyorum - Kısacası - tıpkı güzellik, bakanın gözünde olduğu gibi - set -eve || truefayda, özellikleri ve hedefleriyle tanımlanacak. programcı
Michael,

6
@MichaelFelt Şunu düşünün: git remote remove foo || true git remote add foo http://blah- Uzaktan kumanda yoksa hatayı yoksaymak istiyoruz.
user253751 2 Kasım’da
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.