Mengapa perintah di bawah ini tidak keluar? Alih-alih keluar, loop berjalan tanpa batas.
Sementara saya menemukan perilaku ini menggunakan pengaturan yang lebih kompleks, bentuk perintah yang paling sederhana berkurang menjadi sebagai berikut.
Tidak keluar:
while /usr/bin/true ; do echo "ok" | cat ; done | exit 1
Tidak ada salah ketik di atas. Masing-masing '|' adalah sebuah pipa. 'Keluar 1' adalah proses lain yang berjalan dan keluar.
Saya berharap "keluar 1" menyebabkan SIGPIPE pada loop sementara (tulis pada pipa tanpa pembaca) dan untuk loop keluar. Tapi, loop terus berjalan.
Mengapa perintah itu tidak berhenti?
linux
command-line
bash
shell
bash-scripting
stephen.z
sumber
sumber
Jawaban:
Itu karena pilihan dalam implementasi.
Menjalankan skrip yang sama pada Solaris dengan
ksh93
menghasilkan perilaku yang berbeda:Apa yang memicu masalah adalah pipa bagian dalam, tanpa itu, loop keluar apa pun shell / OS:
cat
mendapatkan sinyal SIGPIPE di bawah bash tetapi shell tetap mengulangi loop.Status dokumentasi Bash :
Dokumentasi Ksh menyatakan:
Status POSIX :
sumber
echo
dibangun mengabaikan SIGPIPE. Anda juga dapat mereproduksi masalah dengan menggunakanenv echo
alih-alihecho
(untuk memaksaecho
biner yang sebenarnya digunakan). (Bandingkan juga output dari{ echo hi; echo $? >&2; } | exit 1
dan{ env echo hi; echo $? >&2; } | exit 1
.)Masalah ini telah mengganggu saya selama bertahun-tahun. Terima kasih kepada jilliagre untuk dorongan ke arah yang benar.
Mengulang sedikit pertanyaan, pada kotak linux saya, ini berhenti seperti yang diharapkan:
Tetapi jika saya menambahkan pipa, itu tidak berhenti seperti yang diharapkan:
Itu membuat saya frustrasi selama bertahun-tahun. Dengan mempertimbangkan jawaban yang ditulis oleh jilliagre, saya menemukan perbaikan yang luar biasa ini:
QED ...
Ya tidak cukup. Ini sesuatu yang sedikit lebih rumit:
Ini tidak berfungsi dengan baik. Saya menambahkan
|| exit
sehingga ia tahu bagaimana cara mengakhiri lebih awal, tetapi yang pertamaecho
tidak cocok dengangrep
begitu loop berhenti segera. Dalam hal ini, Anda benar-benar tidak tertarik pada status keluar darigrep
. Pekerjaan saya adalah menambahkan yang laincat
. Jadi, berikut ini skrip yang dibuat yang disebut "puluhan":Ini benar berakhir ketika dijalankan sebagai
tens | head
. Terima kasih Tuhan.sumber