Bir koşul başarısız olduğunda bash betiği nasıl durdurulur?


11

Burada , komutların yürütülmesini bitirmek için ||ve &&tek bir satırda kullanıldığını gösterir : Bir bash komut dosyasında apt-get hatalarını nasıl kontrol edebilirim?

Belirli bir koşul başarısız olursa bir komut dosyası yürütmeyi durdurmaya çalışıyorum,

Örneğin

false || echo "Obvious error because its false on left" && exit

Burada Obvious error because its false on the leftistediğim şey olan konsolu basar ve çıkar.

true || echo "This shouldn't print" && exit

Burada yankı baskısı yok ama exitkomut da çalışıyor, yani konsol kapalı, exitsağdaki echo komutu yürütülmediği için komut çalıştırılmamalı mı? Veya varsayılan olarak bir &&operatörün sol tarafında yanlış olarak kabul edilen bir ifade midir?

Düzenleme: Daha önce bahsetmiştim, amacım hatayı yankılamak ve net değilse çıkmaktı. & & ve || kullanarak koşulları gruplarken hataları yakalama özel durumum için wrt, @ bodhi.zazen cevap sorunu çözer.

@takatakatek yanıtı akış kontrolü hakkında daha net hale getirir ve bash kılavuz bağlantıları mükemmeldir

muru cevabı, özel hata mesajlarının perl ve trap kullanma alternatifleriyle atılmasını istiyorsanız neden set -e'yi kullanmamanın iyi bir açıklamasına sahip.


Bildiğim kadarıyla senaryo yapılır gibi çıkar.
Panther

Yanıtlar:


10

Muhtemelen istiyorsun (steeldriver tarafından işaret edildiği gibi)

true || { echo "This shouldn't print" && exit; }

Aksi takdirde betiğiniz bir kerede bir koşullu okuyor

a veya b ve ardından çık

Sanırım bir veya (b ve çıkış) istiyor musunuz?


4
Aslında, gereken kullanmak { ... ; }(@steeldriver önerdiği gibi), ya da başka exitsadece altkabuk çıkar ve ebeveyn shell script çalışmaya devam eder.
Gordon Davisson

14

Sorun şu ki || ve &&, durum başarısız olduğunda komut zincirinin yalnızca bir sonraki durmasını atlar. Tam bir blok yapısı yazarsanız, bu mükemmel bir mantıklıdır. Yazdıklarınız şöyle olur:

if ! true ; then
   echo "This shouldn't print"
else
   exit
fi

Ne istiyorsun bu:

if ! true ; then
   echo "This shouldn't print"
   exit
fi

Bash'in kısayol koşullu operatörlerini kullanırken bunları karıştırmaktan kaçınmak daha iyidir. Yazarken mantığı anlamak çok daha kolaydır ve okuyucularınız iyi tarzınızı takdir edecektir.


2
Evet bence bu bash koşullandırma nasıl yazılmalıdır
derHugo

@takatakatek Bu benim durumumda neden başarısız olduğunu daha net hale getiriyor. Bu konuda mantığın açık olduğunu kabul ediyorum ancak && ve || kullanarak koşulları gruplamanın nedeni değil koşullu ifadeler kullanarak ifade etmekten kaçınmak?
kosol

@kosol Evet, && ve || iki şeyi birleştirin: Önceki komutun çıkış durumunu test etme ve yürütülecek (&& için) veya atlanacak (|| için) tek bir komut (veya komut grubu) belirtme. Çok basit durumlar için yararlı olabilirler, ancak tamamen ifade edilen if ... then ... elif ... else ... fiblokların yerini alamazlar. Bash'in daha karmaşık dillerde görülen gerçek boole tiplerine sahip olmadığının farkında olmayabileceğinizden şüpheleniyorum . Bir komutun çıkış durumu 0 (sıfır) ise Bash bunu true / başarılı olarak kabul eder . Çıkış durumu sıfır değilse, Bash bunu false / fail olarak kabul eder .
takatakatek

7

Senaryoyu başlatmakla biraz deneme yapmayı deneyebilirsin

#!/bin/bash -e

-E, betiğin bir şeyin yanlış döndüğü andan çıkmasını sağlar. Daha sonra belirli bir arızadan kaçınılabilir.something || true


7

Hatada başarısız olmanın en basit yolu bash -eseçeneğini kullanmaktır ( set -eveya /bin/bash -eshebang'da). Ancak, bu özel hata mesajları göndermeyi kolaylaştırmaz. Daha basit hale getirebilecek birkaç deyim vardır:

die à la Perl

Perl, stderr'a bir mesaj yazdıran ve genellikle komut dosyasının sonlandırılmasına neden olan bir istisna oluşturan çok uygun bir diekomuta sahiptir. Bunu taklit edebilirsiniz:

die () {
  ret=$?
  print "%s\n" "$@" >&2
  exit "$ret"
}

false || die "Obvious error because its false on left"
true || die "This shouldn't print"

trap ERR

trap <command>Komut sinyali alındığında bir komutu çalıştırmak için kullanılabilir ya da komut (çıkarken edilebilir trap ... EXIT), veya bir komut bir hata verir ( trap ... ERR). Yani şöyle bir şey:

trap 'ret=$?; printf "%s\n" "$ERR_MSG" >&2; exit "$ret"' ERR

Sonra:

ERR_MSG="Obvious error because its false here"
false
ERR_MSG="This shouldn't print"
true

Her iki durumda da, en azından exit 1betiğin başarısız olduğunu belirtmek için kullanmanızı öneririm . Bir düz exit, bu durumda genellikle başarılı olan echoveya printfkomutları olacak olan önceki komutun çıkış durumunu kullanır . Başarısız komutun çıkış durumunu burada yaptığım gibi kaydetmek güzel olurdu.

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.