Pertimbangkan perintahnya
eval false || echo ok
echo also ok
Biasanya, kami mengharapkan ini untuk mengeksekusi false
utilitas dan, karena status keluar tidak nol, untuk kemudian jalankan echo ok
dan echo also ok
.
Dalam semua POSIX-seperti kerang saya gunakan ( ksh93
, zsh
, bash
, dash
, OpenBSD ksh
, dan yash
), ini adalah apa yang terjadi, tetapi hal-hal menarik jika kita aktifkan set -e
.
Jika set -e
berlaku, OpenBSD's sh
dan ksh
shells (keduanya berasal dari pdksh
) akan mengakhiri skrip saat menjalankan eval
. Tidak ada shell lain yang melakukan itu.
POSIX mengatakan bahwa kesalahan dalam utilitas built-in khusus (seperti eval
) harus menyebabkan shell non-interaktif berakhir. Saya tidak sepenuhnya yakin apakah mengeksekusi false
merupakan "kesalahan" (jika ya, itu akan terlepas dari set -e
aktif).
Cara untuk mengatasi ini tampaknya adalah dengan meletakkan eval
di sub shell,
( eval false ) || echo ok
echo also ok
Pertanyaannya adalah apakah saya harus melakukan itu di skrip shell POSIX-ly yang benar, atau apakah itu bug di shell OpenBSD? Juga, apa yang dimaksud dengan "kesalahan" dalam teks POSIX yang ditautkan ke atas?
Info ekstra: Kerang OpenBSD akan menjalankan perintah echo ok
dengan dan tanpa set -e
di perintah
eval ! true || echo ok
Kode asli saya terlihat seperti
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
yang tidak akan menghasilkan not ok
dengan string=false
menggunakan kerang OpenBSD (itu akan berakhir), dan saya tidak yakin itu karena desain, kesalahan atau kesalahpahaman, atau sesuatu yang lain.
eval false
menghasilkan status non-nol jadi saya berharapset -e
untuk mengakhiri skrip pada saat itu. Dalam hal!
set -e
tidak berlaku sebagai!
pernyataan secara eksplisit memeriksa status keluar.eval false
untuk menghentikan skrip walaupun itu bagian dari daftar AND-OR atau pernyataan kondisional? Saya tidak akan.set -e
diatur jika itu adalah perilaku yang benar ... Saya setuju bahwa masuk akal untuk tidak mengakhiri dalam pernyataan bersyarat.set -e
sehingga `()` adalah jawabannya.Jawaban:
Bahwa tidak ada shell lain yang memerlukan penyelesaian seperti itu adalah indikasi kuat bahwa itu adalah bug di OpenBSD ksh. Bahkan, ksh93 tidak menunjukkan masalah seperti itu.
Bahwa ada
||
di dalam baris perintah harus menghindari keluar shell yang disebabkan oleh kode kembali 1 di sebelah kiri itu.Kesalahan dari khusus built-in akan menyebabkan keluar dari shell non interaktif acording POSIX tapi itu tidak selalu benar. Mencoba
continue
keluar dari loop adalah kesalahan, dancontinue
merupakan kesalahan bawaan. Tetapi sebagian besar shell tidak keluar pada:Sebuah builtin yang memancarkan kesalahan yang jelas tetapi tidak keluar.
Jadi, jalan keluar
false
dihasilkan olehset -e
kondisi bukan oleh karakteristik builtin dari perintah (eval
dalam hal ini).Kondisi pasti yang
set -e
akan keluar cukup kabur di POSIX.sumber
[maaf jika ini bukan jawaban yang nyata, saya akan memperbaruinya ketika saya memperbaikinya]
Saya telah melihat kode sumber, dan kesimpulan saya adalah:
1) Ini adalah bug / batasan, tidak ada filosofis di baliknya.
2) "perbaikan" dari garpu portabel ksh (
mksh
) OpenBSD sangat buruk, hanya memperburuk keadaan, tanpa benar-benar memperbaikinya:Bug baru, berbeda dari semua cangkang lain:
Masih belum benar-benar diperbaiki:
Anda dapat mengganti
bash
atas dengandash
,zsh
,yash
,ksh93
, dllsumber