Memeriksa apakah output dari sebuah perintah berisi string tertentu dalam skrip shell

116

Saya sedang menulis skrip shell, dan saya mencoba untuk memeriksa apakah output dari sebuah perintah berisi string tertentu. Saya pikir saya mungkin harus menggunakan grep, tapi saya tidak yakin bagaimana caranya. Apakah ada yang tahu?

pengguna1118764
sumber
Apakah perintah harus tetap berjalan setelah menghasilkan string keluaran yang Anda cari, atau dapatkah segera ditutup pada saat itu? (Kedua jawaban Anda berbeda dalam hal semantiknya dalam hal ini).
Charles Duffy

Jawaban:

97

Uji nilai kembali grep:

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

yang dilakukan secara idiomatis seperti ini:

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

dan juga:

./somecommand | grep -q 'string' && echo 'matched'
nyata
sumber
2
Kode ini tidak bekerja dengan semua shell POSIX: Standar POSIX hanya perlu =menjadi operator pembanding, bukan ==; lihat pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
Charles Duffy
4
Juga, grep 'string' &>/dev/nullkeduanya tidak sesuai dengan POSIX dan jauh lebih lambat untuk dieksekusi (jika stringmuncul lebih awal dalam aliran keluaran yang panjang) daripada grep -q string. [Peringatan ada jika Anda ingin memastikan somecommandtetap berjalan bahkan setelah memancarkan string, dalam hal ini menggunakan grep -q- dengan menutup stdin dan keluar setelah contoh pertama stringterlihat - dapat menjadi kontraproduktif]. (Perihal: "non-POSIX-compliant", &>adalah ekstensi - lihat pubs.opengroup.org/onlinepubs/009695399/utilities/… menjelaskan dukungan pengalihan yang diamanatkan oleh POSIX).
Charles Duffy
Akan membantu jika dijelaskan mengapa itu berfungsi / apa yang dilakukan setiap parameter, untuk mendorong pemahaman penuh tentang sintaks
redfox05
157

Pengujian $?adalah anti-pola

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi
tikar
sumber
Jika kebetulan Anda hanya ingin menguji string tetap, tambahkan opsi F dan x : grep -Fxq F berarti tetap (tidak ditafsirkan) dan x untuk seluruh baris
Erdal G.
4
Mengapa pengujian $?anti-pola?
Vitaly Zdanevich
1
@VitalyZdanevich Saya berasumsi karena tidak kuat terhadap konkurensi.
Konrad Reiche
@VitalyZdanevich, misalnya, pengujian $?tidak menyetel perintah sebelumnya sebagai "dicentang" untuk tujuan set -eatau ERRperangkap, sehingga program Anda dapat keluar jika Anda ingin program tersebut kembali ke jalur sengaja-salah nanti. Di sisi lain, $?adalah keadaan global yang mudah berubah - mudah untuk membuang nilainya secara tidak sengaja. Misalnya, jika Anda menambahkan baris seperti logging echo "Exit status is $?", nilai baru $?menjadi status keluar dari echo.
Charles Duffy
6

Pilihan lainnya adalah memeriksa ekspresi reguler yang cocok pada keluaran perintah.

Sebagai contoh:

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

Skrip shell bersyarat if / else yang bersih:

if ./somecommand | grep -q 'some_string'; then
  echo "exists"
else
  echo "doesn't exist"
fi
Ehsan Barkhordar
sumber