Ada beberapa cara lain untuk mengatasi masalah ini. Dengan asumsi salah satu persyaratan Anda adalah menjalankan skrip / fungsi shell yang berisi beberapa perintah shell dan memeriksa apakah skrip berhasil berjalan dan menampilkan kesalahan jika terjadi kegagalan.
Perintah shell pada umumnya mengandalkan kode keluar yang dikembalikan untuk memberi tahu shell jika berhasil atau gagal karena beberapa kejadian tak terduga.
Jadi apa yang ingin Anda lakukan termasuk dalam dua kategori ini
- keluar karena kesalahan
- keluar dan bersihkan kesalahan
Bergantung pada mana yang ingin Anda lakukan, ada opsi shell yang tersedia untuk digunakan. Untuk kasus pertama, shell menyediakan opsi denganset -e
dan untuk kasus kedua Anda bisa melakukan trap
onEXIT
Haruskah saya gunakan exit
dalam skrip / fungsi saya?
Menggunakan exit
secara umum meningkatkan keterbacaan Dalam rutinitas tertentu, setelah Anda mengetahui jawabannya, Anda ingin segera keluar dari rutinitas panggilan. Jika rutinitas didefinisikan sedemikian rupa sehingga tidak memerlukan pembersihan lebih lanjut setelah mendeteksi kesalahan, tidak segera keluar berarti Anda harus menulis lebih banyak kode.
Jadi dalam kasus jika Anda perlu melakukan tindakan pembersihan pada skrip untuk membuat penghentian skrip bersih, lebih disukai untuk tidak menggunakanexit
.
Haruskah saya gunakan set -e
untuk kesalahan saat keluar?
Tidak!
set -e
adalah upaya untuk menambahkan "deteksi kesalahan otomatis" ke shell. Tujuannya adalah untuk membatalkan shell setiap kali terjadi kesalahan, tetapi ia datang dengan banyak potensi jebakan misalnya,
Perintah yang merupakan bagian dari tes if kebal. Dalam contoh, jika Anda mengharapkannya untuk merusak test
pemeriksaan pada direktori yang tidak ada, itu tidak akan terjadi, itu akan masuk ke kondisi lain
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
Perintah dalam pipa selain yang terakhir, kebal. Dalam contoh di bawah ini, karena kode keluar perintah yang paling baru dijalankan (paling kanan) dianggap ( cat
) dan berhasil. Ini dapat dihindari dengan menetapkan set -o pipefail
opsi tetapi ini masih peringatan.
set -e
somecommand that fails | cat -
echo survived
Direkomendasikan untuk digunakan - trap
saat keluar
Putusannya adalah jika Anda ingin menangani kesalahan alih-alih keluar secara membabi buta, alih-alih menggunakan set -e
, gunakan a trap
pada ERR
sinyal pseudo.
The ERR
perangkap tidak untuk menjalankan kode ketika shell itu sendiri keluar dengan nol non kode kesalahan, tetapi ketika perintah dijalankan oleh yang shell yang bukan merupakan bagian dari kondisi (seperti di jika cmd
, ataucmd ||
) keluar dengan status keluar non-zero .
Praktik umumnya adalah kita mendefinisikan penangan perangkap untuk memberikan informasi debug tambahan pada baris mana dan apa yang menyebabkan keluar. Ingat kode keluar dari perintah terakhir yang menyebabkan ERR
sinyal masih tersedia pada saat ini.
cleanup() {
exitcode=$?
printf 'error condition hit\n' 1>&2
printf 'exit code returned: %s\n' "$exitcode"
printf 'the command executing at the time of the error was: %s\n' "$BASH_COMMAND"
printf 'command present on line: %d' "${BASH_LINENO[0]}"
# Some more clean up code can be added here before exiting
exit $exitcode
}
dan kami hanya menggunakan handler ini seperti di bawah ini di atas skrip yang gagal
trap cleanup ERR
Menyatukan ini pada skrip sederhana yang terdapat false
pada baris 15, informasi yang akan Anda peroleh sebagai
error condition hit
exit code returned: 1
the command executing at the time of the error was: false
command present on line: 15
The trap
juga menyediakan pilihan terlepas dari kesalahan hanya menjalankan pembersihan pada shell selesai (misalnya Anda keluar shell script), pada sinyalEXIT
. Anda juga dapat menangkap banyak sinyal pada saat yang bersamaan. Daftar sinyal yang didukung untuk melakukan trap dapat ditemukan pada halaman manual trap.1p - Linux
Hal lain yang perlu diperhatikan adalah memahami bahwa tidak ada metode yang disediakan yang berfungsi jika Anda berurusan dengan sub-shell yang terlibat dalam hal ini, Anda mungkin perlu menambahkan penanganan kesalahan Anda sendiri.
Pada sub-shell dengan set -e
tidak akan berfungsi. Itu false
dibatasi untuk sub-shell dan tidak pernah disebarkan ke shell induk. Untuk melakukan penanganan kesalahan di sini, tambahkan logika Anda sendiri yang harus dilakukan(false) || false
set -e
(false)
echo survived
Hal yang sama trap
juga terjadi dengan . Logika di bawah ini tidak akan berfungsi karena alasan yang disebutkan di atas.
trap 'echo error' ERR
(false)