Ini adalah pertanyaan lama, tetapi tidak ada jawaban di sini yang membahas penggunaan set -e
alias set -o errexit
dalam skrip penanganan paket Debian. Penggunaan opsi ini wajib dalam skrip ini, sesuai kebijakan Debian; maksudnya adalah untuk menghindari kemungkinan kondisi kesalahan yang tidak tertangani.
Apa artinya ini dalam praktek adalah bahwa Anda harus memahami dalam kondisi apa perintah yang Anda jalankan dapat mengembalikan kesalahan, dan menangani masing-masing kesalahan secara eksplisit.
Gotcha umum adalah eg diff
(mengembalikan kesalahan ketika ada perbedaan) dan grep
(mengembalikan kesalahan ketika tidak ada kecocokan). Anda dapat menghindari kesalahan dengan penanganan eksplisit:
diff this that ||
echo "$0: there was a difference" >&2
grep cat food ||
echo "$0: no cat in the food" >&2
(Perhatikan juga bagaimana kami berhati-hati untuk memasukkan nama skrip saat ini dalam pesan, dan menulis pesan diagnostik ke kesalahan standar alih-alih output standar.)
Jika tidak ada penanganan eksplisit yang benar-benar diperlukan atau berguna, secara eksplisit tidak melakukan apa pun:
diff this that || true
grep cat food || :
(Penggunaan :
perintah no-op shell sedikit tidak jelas, tetapi cukup umum terlihat.)
Hanya untuk menegaskan kembali,
something || other
adalah singkatan
if something; then
: nothing
else
other
fi
yaitu kami secara eksplisit mengatakan other
harus dijalankan jika dan hanya jika something
gagal. Tangan lama if
(dan pernyataan kontrol aliran shell lainnya seperti while
, until
) juga merupakan cara yang valid untuk menangani kesalahan (memang, jika tidak, skrip shell dengan set -e
tidak pernah dapat berisi pernyataan kontrol aliran!)
Dan juga, hanya untuk menjadi eksplisit, dengan tidak adanya penangan seperti ini, set -e
akan menyebabkan seluruh skrip segera gagal dengan kesalahan jika diff
menemukan perbedaan, atau jika grep
tidak menemukan kecocokan.
Di sisi lain, beberapa perintah tidak menghasilkan status keluar kesalahan saat Anda menginginkannya. Perintah yang biasanya bermasalah adalah find
(status keluar tidak mencerminkan apakah file benar-benar ditemukan) dan sed
(status keluar tidak akan mengungkapkan apakah skrip menerima input atau benar-benar menjalankan perintah dengan sukses). Penjaga sederhana dalam beberapa skenario adalah menyalurkan ke perintah yang tidak menjerit jika tidak ada output:
find things | grep .
sed -e 's/o/me/' stuff | grep ^
Perlu dicatat bahwa status keluar dari pipa adalah status keluar dari perintah terakhir dalam pipa itu. Jadi perintah di atas benar-benar sepenuhnya menutupi status find
dan sed
, dan hanya memberi tahu Anda apakah grep
akhirnya berhasil.
(Bash, tentu saja, memiliki set -o pipefail
; tetapi skrip paket Debian tidak dapat menggunakan fitur Bash. Kebijakan dengan tegas menentukan penggunaan POSIX sh
untuk skrip ini, meskipun hal ini tidak selalu terjadi.)
Dalam banyak situasi, ini adalah sesuatu yang harus diperhatikan secara terpisah ketika melakukan pengkodean secara defensif. Kadang-kadang Anda harus misalnya pergi melalui file sementara sehingga Anda dapat melihat apakah perintah yang menghasilkan output selesai dengan sukses, bahkan ketika idiom dan kenyamanan sebaliknya mengarahkan Anda untuk menggunakan pipa shell.