Jika Anda benar-benar tidak ingin perintah kedua dilanjutkan hingga perintah pertama berhasil, Anda mungkin perlu menggunakan file sementara. Versi sederhananya adalah:
tmp=${TMPDIR:-/tmp}/mine.$$
if ./a > $tmp.1
then
if ./b <$tmp.1 >$tmp.2
then
if ./c <$tmp.2
then : OK
else echo "./c failed" 1>&2
fi
else echo "./b failed" 1>&2
fi
else echo "./a failed" 1>&2
fi
rm -f $tmp.[12]
Pengalihan '1> & 2' juga dapat disingkat '> & 2'; Namun, versi lama dari shell MKS salah menangani pengalihan kesalahan tanpa '1' sebelumnya jadi saya telah menggunakan notasi yang tidak ambigu untuk keandalan selama berabad-abad.
Ini membocorkan file jika Anda mengganggu sesuatu. Pemrograman shell tahan bom (lebih atau kurang) menggunakan:
tmp=${TMPDIR:-/tmp}/mine.$$
trap 'rm -f $tmp.[12]; exit 1' 0 1 2 3 13 15
...if statement as before...
rm -f $tmp.[12]
trap 0 1 2 3 13 15
Baris perangkap pertama mengatakan 'jalankan perintah' rm -f $tmp.[12]; exit 1
ketika salah satu sinyal 1 SIGHUP, 2 SIGINT, 3 SIGQUIT, 13 SIGPIPE, atau 15 SIGTERM terjadi, atau 0 (ketika shell keluar karena alasan apa pun). Jika Anda menulis skrip shell, perangkap terakhir hanya perlu menghapus perangkap di 0, yang merupakan perangkap keluar shell (Anda dapat membiarkan sinyal lain di tempatnya karena prosesnya akan segera berakhir).
Dalam pipeline asli, 'c' layak untuk membaca data dari 'b' sebelum 'a' selesai - ini biasanya diinginkan (ini memberikan banyak inti pekerjaan yang harus dilakukan, misalnya). Jika 'b' adalah fase 'sort', maka ini tidak akan berlaku - 'b' harus melihat semua inputnya sebelum dapat menghasilkan output apa pun.
Jika Anda ingin mendeteksi perintah mana yang gagal, Anda dapat menggunakan:
(./a || echo "./a exited with $?" 1>&2) |
(./b || echo "./b exited with $?" 1>&2) |
(./c || echo "./c exited with $?" 1>&2)
Ini sederhana dan simetris - sangat mudah untuk diperpanjang ke pipa 4-bagian atau N-bagian.
Eksperimen sederhana dengan 'set -e' tidak membantu.
&&|
yang berarti "hanya lanjutkan pipa jika perintah sebelumnya berhasil". Saya kira Anda juga bisa memiliki|||
yang berarti "lanjutkan pipa jika perintah sebelumnya gagal" (dan mungkin menyalurkan pesan kesalahan seperti Bash 4|&
).