Saya telah membaca banyak pertanyaan tentang berbagai situs pertukaran stack dan unix forum bantuan tentang cara memodifikasi opsi shell dan kemudian mengembalikannya - yang paling komprehensif yang saya temukan di sini adalah di Bagaimana "membatalkan" a `set -x`?
The kebijaksanaan yang diterima tampaknya baik menyimpan dari hasil set +oatau shopt -pokemudian evalnanti untuk mengembalikan pengaturan sebelumnya.
Namun, dalam pengujian saya sendiri dengan bash 3.x dan 4.x, errexitopsi tidak disimpan dengan benar saat melakukan penggantian perintah.
Berikut ini contoh skrip untuk menunjukkan masalah:
set -o errexit
set -o nounset
echo "LOCAL SETTINGS:"
set +o
OLDOPTS=$(set +o)
echo
echo "SAVED SETTINGS:"
echo "$OLDOPTS"
Dan output (saya memangkas beberapa variabel yang tidak relevan):
LOCAL SETTINGS:
set -o errexit
set -o nounset
SAVED SETTINGS:
set +o errexit
set -o nounset
Ini sepertinya sangat berbahaya. Kebanyakan skrip yang saya tulis bergantung pada errexitpenghentian eksekusi jika ada perintah yang gagal. Saya baru saja menemukan bug di salah satu skrip saya yang disebabkan oleh ini, di mana fungsi yang seharusnya mengembalikan errexitpada akhirnya berakhir dengan menimpanya, mengaturnya kembali ke default off selama durasi skrip.
Yang ingin saya lakukan adalah menulis fungsi yang dapat mengatur opsi sesuai kebutuhan dan kemudian mengembalikan semua opsi dengan benar sebelum keluar. Tetapi tampaknya seolah-olah dalam subkulit dipanggil oleh substitusi perintah, errexittidak diwarisi.
Saya bingung bagaimana cara menyelamatkan hasil set +otanpa menggunakan substitusi perintah atau melompat melalui lingkaran FIFO. Saya dapat membaca dari $SHELLOPTStetapi evalformatnya tidak bisa ditulis atau dalam -able.
Saya tahu salah satu alternatifnya adalah menggunakan fungsi subshell , tapi itu memperkenalkan banyak sakit kepala karena bisa mencatat output dan juga mengembalikan beberapa variabel.
Mungkin terkait: /programming/29532904/bash-subshell-errexit-semantics (sepertinya ada solusi untuk bash 4.4 dan yang lebih tinggi, tetapi saya lebih suka memiliki solusi portabel)
shoptopsi set bash (seperti nullglob).