idiom `set -e` dan` grep` untuk mencegah keluar prematur dari skrip shell ketika pola tidak ditemukan

15

Diperlukan bantuan - dalam konteks skrip shell pada bash GNU / LINUX:

Saya selalu menggunakan set -e. Seringkali, saya ingin grepdan tidak selalu ingin skrip menghentikan eksekusi jika grepmemiliki status keluar yang 1menunjukkan pola tidak ditemukan.

Sesuatu yang saya coba untuk memecahkan masalah ini adalah sebagai berikut:

(Coba saya)
Jika set +o pipefaildan aktifkan grep dengan sesuatu seperti grep 'p' | wc -lmaka saya mendapatkan perilaku yang diinginkan sampai pengelola masa depan memungkinkan pipefail. Saya juga suka mengaktifkan pipefailjadi ini tidak berfungsi untuk saya.

(Coba II)
Gunakan pola pencocokan garis cetak dan sedatau awkhanya, kemudian wcgaris yang cocok untuk menguji pola yang cocok. Aku tidak suka pilihan ini karena menggunakan seduntuk greptampak seperti solusi untuk masalah saya benar.

(Coba III) Yang
ini adalah favorit saya yang paling sedikit - seperti:set +e; grep 'p'; set-e

Setiap wawasan / idiom akan sangat dihargai - terima kasih.

Yeow_Meng
sumber

Jawaban:

19

Anda dapat menempatkan grep dalam ifkondisi, atau jika Anda tidak peduli tentang status keluar, tambahkan || true.

Contoh: grepmembunuh shell

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

solusi 1: buang status keluar yang tidak nol

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

solusi 2: secara eksplisit menguji status keluar

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

Dari halaman bash man yang membahas set -e:

Shell tidak keluar jika perintah yang gagal adalah bagian dari daftar perintah segera setelah beberapa saat atau sampai kata kunci, bagian dari pengujian mengikuti kata if atau elif yang dilindungi, bagian dari perintah yang dieksekusi dalam daftar && atau ││ kecuali perintah mengikuti akhir && atau ││ , perintah apa pun dalam pipa kecuali yang terakhir, atau jika nilai pengembalian perintah sedang dibalik dengan ! .

glenn jackman
sumber
Mengingat bahwa bash untuk waktu yang lama tidak menerapkan -e dengan benar, mungkin dokumentasi tersebut belum benar. Karena teks tampaknya identik dengan halaman manual bash-3.x, harap dicatat: semua versi bash sebelum bash4.0 menerapkan -e secara tidak benar.
schily
Juga perhatikan bahwa karena standar POSIX salah, kami mengubah teks POSIX untuk penanganan kesalahan dengan -e pada 2009
schily
1
@schily Tolong beri petunjuk ke mana orang bisa mengetahui apa perilaku 'benar' dari -e adalah, apa bash <4 lakukan secara berbeda, dan apa yang diubah dalam POSIX.
zwol
Bug di bash-3 pada dasarnya membuatnya tidak dapat digunakan karena maketidak selalu keluar karena kesalahan. Untuk diskusi POSIX terkait, Anda mungkin ingin memeriksa austingroupbugs.net
schily
@schily Bisakah Anda lebih spesifik?
zwol