Eksekusi (exit 1);
adalah cara paling sederhana untuk memicu ERR
jebakan. Ini juga akan memicu keluar segera jika set -e
sedang berlaku. (Memicu kondisi kesalahan memerlukan perintah untuk gagal; exit
dengan nilai kegagalan dalam subkulit menyebabkan subkulit gagal.)
exit 1;
tidak akan melakukan hal-hal itu.
Jadi {(exit 1); exit 1;}
dapat digunakan untuk pertama-tama menghasilkan ERR
jebakan, yang mungkin melakukan sesuatu yang berguna untuk tujuan debugging, dan kemudian mengakhiri skrip dengan indikasi kesalahan.
Tapi bukan itu yang terjadi dalam autoconf
file. autoconf
skrip mengandalkan EXIT
jebakan untuk membersihkan file sementara yang dibuat selama proses. Kebanyakan shell, termasuk bash
akan mengatur status dari nilai yang disediakan dalam exit
perintah sebelum memanggil EXIT
jebakan. Itu dapat memungkinkan EXIT
perangkap untuk mendeteksi apakah itu dipanggil dari kesalahan atau dari penghentian normal, dan itu juga memungkinkan untuk memastikan bahwa status keluar diatur dengan benar di akhir operasi perangkap.
Namun, tampaknya beberapa cangkang tidak bekerja sama. Berikut ini kutipan dari autoconf
manual :
Beberapa skrip shell, seperti yang dihasilkan oleh autoconf
, menggunakan perangkap untuk membersihkan sebelum keluar. Jika perintah shell terakhir keluar dengan status bukan nol, jebakan juga keluar dengan status bukan nol sehingga penyerang dapat mengetahui bahwa terjadi kesalahan.
Sayangnya, dalam beberapa shell, seperti Solaris /bin/sh
, trap keluar mengabaikan argumen perintah keluar. Dalam shell ini, jebakan tidak dapat menentukan apakah itu dipanggil dengan keluar biasa atau dengan keluar 1. Alih-alih memanggil keluar secara langsung, gunakan AC_MSG_ERROR
makro yang memiliki solusi untuk masalah ini.
Solusi adalah untuk memastikan bahwa $?
memiliki status exit sebelum itu exit
perintah dijalankan, sehingga pasti akan memiliki nilai bahwa ketika EXIT
perangkap dijalankan. Dan, memang, itu adalah AC_MSG_ERROR
makro yang menyisipkan kode aneh itu, lengkap dengan kawat gigi redundan.
false
saja(exit 1)
?false
jangan biarkan Anda mengatur kode status dan tidak ada jaminan untuk apa status non-nol itu dikembalikan. (2)false
biasanya tidak builtin, sehingga membutuhkan proses anak; sebaliknya, sebagian besar cangkang dapat menghindari pemijahan anak untuk ditangani(exit 1)
.Tidak ada tujuan untuk ini sejauh yang saya lihat, tidak ada yang dapat dicapai secara langsung dengan memulai subkulit dan kemudian segera keluar.
Hal-hal seperti ini kemungkinan besar merupakan efek samping dari pembuatan kode secara otomatis - dalam beberapa kasus mungkin ada perintah lain yang dijalankan dalam subkulit di mana memiliki
exit 1
akal. Pada akhirnya ada peluang yang baik bahwa kode generasi entah bagaimana disederhanakan dengan membiarkannya memasukkan beberapa pernyataan yang tidak memiliki fungsi dalam beberapa kasus dan menghasilkan 'kode bersih' setiap kali lebih kompleks. Entah itu atau kode yang menghasilkan di atas ditulis dengan buruk :)Penggunaan liberal
{...}
adalah contoh lain dari ini, kebanyakan dari mereka berlebihan, tetapi lebih mudah untuk menulis kode yang menyisipkan mereka dalam setiap kasus (mungkin dalam beberapa Anda ingin mengarahkan output / input dari blok) daripada membedakan yang tidak dibutuhkan dan dihilangkan.sumber
(exit 1)
adalah cara yang sederhana, mungkin cara paling sederhana untuk mendapatkan kode keluar tertentu (dalam kasus khusus 1 ada cara yang lebih mudah, tentu saja). Tapi itu bukan alasan dalam hal ini karena kode keluar tidak diperiksa.Tujuan memasukkan
exit
subkulit mungkin untuk tidak keluar dari skrip (meskipun menggunakan keluar untuk pembuatan kode keluar tertentu).sumber