Untuk membuat pipeline zsh melaporkan kegagalan dari tahap mana pun, aktifkan opsi PIPE_FAIL sebelum menjalankannya. Di Terminal pada Mac, masukkan setopt PIPE_FAIL; dalam sebuah skrip, letakkan baris tersebut sebelum pipeline. Pipeline kemudian akan mengembalikan status keluar dari perintah paling kanan yang gagal, atau nol jika setiap perintah berhasil. Simpan $? segera setelah pipeline jika perintah selanjutnya tidak boleh menggantikan hasil tersebut. Manual opsi zsh mendokumentasikan perilaku ini.

Mengapa pipeline yang gagal bisa terlihat berhasil

Secara default, zsh memberikan status keluar dari perintah terakhirnya kepada sebuah pipeline. Jadi, jika perintah sebelumnya gagal tetapi perintah terakhir berhasil, pipeline secara keseluruhan dapat terlihat berhasil. Sebagai contoh, perintah cat terakhir di bawah ini dapat berhasil meskipun grep tidak menemukan baris yang cocok:

printf '%s\n' 'ready' | grep 'missing' | cat
print -r -- $?

Manual zsh mendefinisikan pipeline sebagai perintah-perintah yang digabungkan dengan | dan menyatakan nilainya biasanya adalah nilai dari perintah terakhir. Status nol berarti berhasil; status bukan nol berarti perintah atau pipeline melaporkan kegagalan. Dokumentasi pipeline zsh menjelaskan aturan default ini.

Aktifkan PIPE_FAIL untuk pipeline

Dalam sesi Terminal, atur opsi ini sebelum menjalankan perintah:

setopt PIPE_FAIL
printf '%s\n' 'ready' | grep 'missing' | cat
print -r -- $?

Status akhirnya sekarang bukan nol karena grep gagal, meskipun cat berhasil. PIPE_FAIL menggunakan status bukan nol yang paling kanan dalam pipeline. Hal ini menjaga agar kegagalan tetap bermakna sambil tetap mengembalikan kode status sebenarnya yang dipilih oleh zsh. Untuk menonaktifkan kembali perilaku ini dalam sesi yang sama, jalankan unsetopt PIPE_FAIL.

Untuk sebuah skrip, letakkan opsi ini di dekat bagian atas, setelah baris penerjemah (interpreter) dan sebelum pipeline yang terpengaruh:

#!/bin/zsh
setopt PIPE_FAIL

printf '%s\n' 'ready' | grep 'missing' | cat
pipeline_status=$?

if (( pipeline_status != 0 )); then
  print -u2 -- "Pipeline failed with status $pipeline_status"
  exit "$pipeline_status"
fi

Penetapan status secara eksplisit sangat penting: $? berarti status dari perintah terakhir, sehingga perintah print berikutnya, perintah terkait variabel, atau kondisional dapat mengubah apa yang dilaporkannya. Menyimpan nilai tersebut segera memungkinkan skrip untuk melaporkannya atau keluar dengannya setelah pekerjaan lain. Contoh ini mengembalikan status gagal ke program yang meluncurkan skrip; ini tidak menghentikan perintah individual dalam pipeline untuk berjalan begitu tahap sebelumnya gagal.

Gunakan pipestatus saat Anda memerlukan hasil dari setiap tahap

PIPE_FAIL merangkum pipeline. Jika Anda juga perlu mengidentifikasi perintah mana yang mengembalikan kode tertentu, zsh menyediakan larik khusus pipestatus, yang berisi status dari setiap perintah dalam pipeline terakhir. Baca nilai ini segera, karena pipeline lain akan menggantikan nilai-nilai tersebut. Referensi parameter zsh mendokumentasikan larik ini.

printf '%s\n' 'ready' | grep 'missing' | cat
print -r -- "Stage statuses: ${pipestatus[*]}"

Untuk contoh tiga perintah ini, output menunjukkan angka nol untuk printf, nilai bukan nol untuk grep, dan angka nol untuk cat. Kode bukan nol yang tepat bergantung pada perintahnya. Jika Anda memerlukan hasil keseluruhan sekaligus hasil per tahap, gunakan PIPE_FAIL dan simpan $? keseluruhan secara langsung; periksa pipestatus segera setelah eksekusi pipeline terpisah saat mendiagnosis tahapan, atau rancang skrip untuk mencatat larik terlebih dahulu dan menghitung agregat yang diinginkan dari data yang disimpan tersebut. Hindari menyisipkan perintah atau pipeline lain di antara pipeline dan status yang ingin Anda baca.

Pertahankan pengaturan di shell yang tepat

Untuk menerapkan opsi ini ke perintah-perintah selanjutnya dalam sesi zsh interaktif, jalankan setopt PIPE_FAIL dalam sesi tersebut. Untuk mengaktifkannya pada setiap sesi zsh baru, tambahkan baris tersebut ke ~/.zshrc, lalu buka jendela Terminal baru atau muat ulang berkas dengan source ~/.zshrc. Panduan Terminal Apple menetapkan zsh sebagai shell default, sembari mencatat bahwa pengaturan atau administrator dapat memilih shell yang berbeda. Pastikan shell yang aktif sebelum mengandalkan sintaks khusus zsh. Panduan Terminal Apple menjelaskan cara Terminal memilih shell.

Skrip yang diawali dengan #!/bin/zsh meminta zsh secara langsung, terlepas dari shell interaktif yang dikonfigurasi untuk Terminal. Jika skrip justru dijalankan oleh shell lain, setopt dan pipestatus bukanlah pengganti portabel untuk kontrol pipeline milik shell tersebut. Jaga agar penerjemah dan sintaks tetap selaras, lalu pertahankan hasil pipeline sebelum melakukan pekerjaan lanjutan.

Sumber