Pertimbangkan cuplikan ini:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Biasanya ketika func
dipanggil itu akan menyebabkan script untuk mengakhiri, yang merupakan perilaku yang dimaksud. Namun, jika dijalankan dalam sub-shell, seperti di
result=`func`
itu tidak akan keluar dari skrip. Ini berarti kode panggilan harus memeriksa status keluar dari fungsi setiap kali. Apakah ada cara untuk menghindari ini? Apakah ini untuk apa set -e
?
shell
shell-script
exit
subshell
Ernest AC
sumber
sumber
func
.Jawaban:
Anda dapat membunuh shell asli (
kill $$
) sebelum memanggilexit
, dan itu mungkin berhasil. Tapi:Sebagai gantinya, Anda bisa menggunakan salah satu dari beberapa cara untuk mengembalikan nilai dalam Bash FAQ . Sayangnya, kebanyakan dari mereka tidak begitu hebat. Anda mungkin hanya terjebak memeriksa kesalahan setelah setiap panggilan fungsi (
-e
memiliki banyak masalah ) Entah itu, atau beralih ke Perl.sumber
Anda dapat memutuskan bahwa status keluar 77 misalnya berarti keluar dari setiap tingkat subkulit, dan lakukan
set -E
dalam kombinasi denganERR
jebakan agak mirip dengan versi yang disempurnakanset -e
yang memungkinkan Anda untuk menentukan penanganan kesalahan Anda sendiri.Di zsh, ERR traps diwarisi secara otomatis, jadi Anda tidak perlu
set -E
, Anda juga dapat mendefinisikan jebakan sebagaiTRAPERR()
fungsi, dan memodifikasinya$functions[TRAPERR]
, sepertifunctions[TRAPERR]="echo was here; $functions[TRAPERR]"
sumber
kill $$
.echo "$(exit 77)"
; script akan melanjutkan seolah-olah kita telah menulisecho ""
Sebagai alternatif
kill $$
, Anda juga dapat mencobakill 0
, ini akan berfungsi dalam kasus subshell bersarang (semua penelepon dan proses samping akan menerima sinyal) ... tetapi masih brutal dan jelek.sumber
Coba ini ...
Hasil yang saya dapatkan adalah ...
Catatan
if
tes menjaditrue
ataufalse
(lihat 2 berjalan)if
tes inifalse
, kami tidak pernah mencapai subkulit.sumber
(Jawaban spesifik Bash) Bash tidak memiliki konsep pengecualian. Namun, dengan set -o errexit (atau yang setara: set -e) di level terluar, perintah yang gagal akan menghasilkan subkulit yang keluar dengan status keluar yang tidak nol. Jika ini adalah satu set subkulit bersarang tanpa persyaratan di sekitar pelaksanaan subkulit tersebut, ini akan secara efektif 'menggulung' seluruh skrip dan keluar.
Ini bisa rumit ketika mencoba memasukkan bit dari berbagai kode bash ke dalam skrip yang lebih besar. Satu bash bash mungkin bekerja dengan baik sendiri, tetapi ketika dieksekusi di bawah errexit (atau tanpa errexit), berperilaku dengan cara yang tidak terduga.
sumber
Contoh saya untuk keluar dalam satu liner:
sumber