Abstrak
Untuk membalikkan set -x
hanya menjalankan a set +x
. Sebagian besar waktu, kebalikan dari string set -str
adalah string yang sama dengan +
: set +str
.
Secara umum, untuk mengembalikan semua (baca di bawah tentang bash errexit
) opsi shell (diubah dengan set
perintah) yang dapat Anda lakukan (juga baca di bawah tentang shopt
opsi bash ):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
Deskripsi yang lebih panjang
pesta
Perintah ini:
shopt -po xtrace
akan menghasilkan string yang dapat dieksekusi yang mencerminkan keadaan opsi. The p
berarti bendera mencetak, dan o
menspesifikasikan flag yang kita bertanya tentang pilihan (s) yang ditetapkan oleh set
perintah (sebagai lawan pilihan (s) yang ditetapkan oleh shopt
perintah). Anda dapat menetapkan string ini ke variabel, dan menjalankan variabel di akhir skrip Anda untuk mengembalikan keadaan awal.
# store state of xtrace option.
tracestate="$(shopt -po xtrace)"
# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"
# restore the value of xtrace to its original value.
eval "$tracestate"
Solusi ini berfungsi untuk beberapa opsi secara bersamaan:
oldstate="$(shopt -po xtrace noglob errexit)"
# change options as needed
set -x
set +x
set -f
set -e
set -x
# restore to recorded state:
set +vx; eval "$oldstate"
Menambahkan set +vx
menghindari pencetakan daftar opsi yang panjang.
Dan, jika Anda tidak mencantumkan nama opsi,
oldstate="$(shopt -po)"
ini memberi Anda nilai dari semua opsi. Dan, jika Anda meninggalkan o
benderanya, Anda dapat melakukan hal yang sama dengan shopt
opsi:
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
Jika Anda perlu menguji apakah suatu set
opsi diset, cara paling idiomatis (Bash) untuk melakukannya adalah:
[[ -o xtrace ]]
yang lebih baik dari dua tes serupa lainnya:
[[ $- =~ x ]]
[[ $- == *x* ]]
Dengan salah satu tes, ini berfungsi:
# record the state of the xtrace option in ts (tracestate):
[ -o xtrace ] && ts='set -x' || ts='set +x'
# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"
# set the xtrace option back to what it was.
eval "$ts"
Berikut cara menguji keadaan shopt
opsi:
if shopt -q dotglob
then
# dotglob is set, so “echo .* *” would list the dot files twice.
echo *
else
# dotglob is not set. Warning: the below will list “.” and “..”.
echo .* *
fi
POSIX
Solusi sederhana yang sesuai dengan POSIX untuk menyimpan semua set
opsi adalah:
set +o
yang dijelaskan dalam standar POSIX sebagai:
+ o
Tulis pengaturan opsi saat ini ke output standar dalam format yang sesuai untuk dimasukkan kembali ke shell sebagai perintah yang mencapai pengaturan opsi yang sama.
Jadi, cukup:
oldstate=$(set +o)
akan mempertahankan nilai untuk semua opsi yang ditetapkan menggunakan set
perintah.
Sekali lagi, mengembalikan opsi ke nilai aslinya adalah masalah mengeksekusi variabel:
set +vx; eval "$oldstate"
Ini persis sama dengan menggunakan Bash shopt -po
. Perhatikan bahwa itu tidak akan mencakup semua opsi Bash yang mungkin , karena beberapa di antaranya ditetapkan oleh shopt
.
bash kasus khusus
Ada banyak opsi shell lain yang terdaftar shopt
di dalam bash:
$ shopt
autocd off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize on
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
compat42 off
compat43 off
complete_fullquote on
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases on
extdebug off
extglob off
extquote on
failglob off
force_fignore on
globasciiranges off
globstar on
gnu_errfmt off
histappend on
histreedit off
histverify on
hostcomplete on
huponexit off
inherit_errexit off
interactive_comments on
lastpipe on
lithist off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
Itu bisa ditambahkan ke set variabel di atas dan dikembalikan dengan cara yang sama:
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
Itu mungkin dilakukan ( $-
ditambahkan untuk memastikan errexit
dilestarikan):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
Catatan : setiap shell memiliki cara yang sedikit berbeda untuk membangun daftar opsi yang disetel atau tidak disetel (belum lagi opsi yang berbeda yang ditentukan), sehingga string tidak portabel di antara shell, tetapi berlaku untuk shell yang sama.
kasus khusus zsh
zsh
juga berfungsi dengan benar (mengikuti POSIX) sejak versi 5.3. Dalam versi sebelumnya, ia hanya mengikuti POSIX sebagian dengan set +o
mencetak opsi dalam format yang sesuai untuk diinput ke shell sebagai perintah, tetapi hanya untuk opsi set (tidak mencetak opsi yang tidak disetel ).
kasus khusus mksh
Mksh (dan sebagai konsekuensi lksh) belum (MIRBSD KSH R54 2016/11/11) dapat melakukan ini. Manual mksh berisi ini:
Dalam versi yang akan datang, set + o akan berperilaku sesuai perintah POSIX dan mencetak untuk mengembalikan opsi saat ini.
set -e kasus khusus
Di bash, nilai set -e
( errexit
) diatur ulang di dalam sub-shell, yang membuatnya sulit untuk menangkap nilainya dengan set +o
di dalam sub-shell $ (...).
Sebagai solusinya, gunakan:
oldstate="$(set +o); set -$-"
oldstate=$(set +o)
adalah cara yang lebih sederhana (dan POSIX) untuk menyimpan semua opsi.pdksh
/mksh
(dan turunan pdksh lainnya) atau dizsh
manaset +o
hanya menampilkan penyimpangan dari pengaturan default. Itu akan bekerja untuk bash / dash / yash tetapi tidak portabel.Anda dapat membaca
$-
variabel di awal untuk melihat apakah-x
sudah diatur atau tidak dan kemudian simpan ke variabel misalnyaDari manual Bash :
sumber
Dalam bash, $ SHELLOPTS disetel dengan bendera yang dihidupkan. Periksa sebelum Anda menyalakan xtrace, dan setel ulang xtrace hanya jika dimatikan sebelumnya.
sumber
Hanya untuk menyatakan yang sudah jelas, jika
set -x
akan berlaku selama durasi skrip, dan ini hanyalah ukuran pengujian sementara (tidak menjadi bagian dari output secara permanen), maka jalankan skrip dengan-x
opsi, misalnya,... atau, ubah sementara skrip (baris pertama) untuk mengaktifkan hasil debug dengan menambahkan
-x
opsi:Saya menyadari ini mungkin stroke yang terlalu luas untuk apa yang Anda inginkan, tetapi ini adalah cara paling sederhana & tercepat untuk mengaktifkan / menonaktifkan, tanpa terlalu menyulitkan skrip dengan hal-hal sementara yang mungkin ingin Anda hapus (menurut pengalaman saya).
sumber
Ini menyediakan fungsi untuk menyimpan dan mengembalikan flag yang terlihat melalui
$-
parameter khusus POSIX . Kami menggunakanlocal
ekstensi untuk variabel lokal. Dalam skrip portabel yang sesuai dengan POSIX, variabel global akan digunakan (tanpalocal
kata kunci):Ini digunakan mirip dengan bagaimana flag interupsi disimpan dan dipulihkan di kernel Linux:
Ini tidak akan berfungsi untuk semua opsi yang diperluas yang tidak tercakup dalam
$-
variabel.Hanya memperhatikan bahwa POSIX memiliki apa yang saya cari:
+o
argumenset
bukanlah pilihan, tetapi perintah yang membuang banyak perintah yang, jikaeval
-ed akan mengembalikan opsi. Begitu:Itu dia.
Satu masalah kecil adalah bahwa jika
-x
opsi diubah sebelum inieval
, kesibukanset -o
perintah terlihat. Untuk menghilangkan ini, kita dapat melakukan hal berikut:sumber
Anda dapat menggunakan sub-shell.
sumber
Mirip dengan apa yang dikatakan @Jeff Shaller tetapi diatur ke TIDAK gema bagian di tengah (yang saya butuhkan):
sumber