Bir komutun çıktısının bir kabuk komut dosyasında belirli bir dizge içerip içermediğini kontrol etme


117

Bir kabuk betiği yazıyorum ve bir komutun çıktısının belirli bir dizge içerip içermediğini kontrol etmeye çalışıyorum. Muhtemelen grep kullanmam gerektiğini düşünüyorum, ama nasıl olduğundan emin değilim. Kimse biliyor mu?


Komutun aradığınız çıktı dizesini oluşturduktan sonra çalışmaya devam etmesi gerekiyor mu, yoksa o anda hemen kapatılabilir mi? (Sizin iki cevabınız bu açıdan anlam bakımından farklılık gösterir).
Charles Duffy

Yanıtlar:


97

Grep'in dönüş değerini test edin:

./somecommand | grep 'string' &> /dev/null
if [ $? == 0 ]; then
   echo "matched"
fi

bu deyimsel olarak şöyle yapılır:

if ./somecommand | grep -q 'string'; then
   echo "matched"
fi

ve ayrıca:

./somecommand | grep -q 'string' && echo 'matched'

2
Bu kod tüm POSIX kabuklarında çalışmaz: POSIX standardı yalnızca =bir karşılaştırma operatörü olmayı gerektirir , değil ==; bkz pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
Charles Duffy

4
Ayrıca, grep 'string' &>/dev/nullhem POSIX uyumlu değildir hem de yürütmesi ( stringuzun bir çıktı akışında erken görünürse) olduğundan çok daha yavaştır grep -q string. [Emin olmak istiyorsanız buradaki uyarı, yaydıktan somecommandsonra bile çalışmaya devam etmesidir string, bu durumda kullanmak grep -q- stdinini kapatarak ve ilk stringgörüldükten sonra çıkarak - verimsiz olabilir]. (Re: "POSIX uyumlu olmayan" &>bir uzantıdır - POSIX tarafından zorunlu tutulan yeniden yönlendirme desteğini açıklayan pubs.opengroup.org/onlinepubs/009695399/utilities/… 'e bakın ).
Charles Duffy

Sözdiziminin tam olarak anlaşılmasını teşvik etmek için neden işe yaradığı / her parametrenin ne yaptığı
açıklansaydı yardımcı olurdu

158

Test $?bir anti-modeldir

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi

Şans eseri sadece sabit bir dizeyi test etmek istiyorsanız, F ve x seçeneklerini ekleyin : grep -Fxq F sabit (yorumlanmamış) anlamına gelir ve tüm satır için x
Erdal G.

4
Neden test etmek $?anti-modeldir?
Vitaly Zdanevich

1
@VitalyZdanevich Sanırım eşzamanlılığa karşı sağlam değil.
Konrad Reiche

@VitalyZdanevich, birincisi, test etme $?, önceki komutları tuzak set -eveya ERRtuzak amacıyla "işaretli" olarak ayarlamaz , böylece programınız daha sonra kasıtlı olarak yanlış yola geri dönmesini istediğiniz durumlarda çıkabilir. Bir diğeri için, $?değişken küresel durum - değerini tesadüfen atmak kolaydır. Örneğin, gibi bir günlük kaydı satırı eklerseniz echo "Exit status is $?", içindeki yeni değer $?, çıkış durumu olur echo.
Charles Duffy

6

Diğer bir seçenek, komut çıktısında düzenli ifade eşleşmesini kontrol etmektir.

Örneğin:

[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"

1

Temiz bir if / else koşullu kabuk betiği:

if ./somecommand | grep -q 'some_string'; then
  echo "exists"
else
  echo "doesn't exist"
fi
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.