मैं set -x
अपनी स्क्रिप्ट की शुरुआत में और इसे "पूर्ववत करना" चाहता हूं (अंधाधुंध सेट करने से पहले राज्य में वापस जाऊंगा) +x
। क्या यह संभव है?
पुनश्च: मैं पहले ही यहाँ जाँच कर चुका हूँ ; जहाँ तक मैं बता सकता हूँ मेरे सवाल का जवाब नहीं लगता था।
मैं set -x
अपनी स्क्रिप्ट की शुरुआत में और इसे "पूर्ववत करना" चाहता हूं (अंधाधुंध सेट करने से पहले राज्य में वापस जाऊंगा) +x
। क्या यह संभव है?
पुनश्च: मैं पहले ही यहाँ जाँच कर चुका हूँ ; जहाँ तक मैं बता सकता हूँ मेरे सवाल का जवाब नहीं लगता था।
जवाबों:
रिवर्स करने के लिए set -x
बस एक निष्पादित करें set +x
। ज्यादातर समय, एक स्ट्रिंग set -str
का उलटा एक ही स्ट्रिंग है +
: a set +str
।
सामान्य तौर पर, सभी को पुनर्स्थापित करने के लिए (बैश के बारे में नीचे पढ़ें errexit
) शेल विकल्प ( set
कमांड के साथ बदला हुआ ) जो आप कर सकते हैं (नीचे दिए गए shopt
विकल्पों के बारे में भी पढ़ें ):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
यह आदेश:
shopt -po xtrace
एक निष्पादन योग्य स्ट्रिंग उत्पन्न करेगा जो विकल्प की स्थिति को दर्शाता है। p
झंडा साधन प्रिंट, और o
ध्वज को निर्दिष्ट है कि हम के बारे में विकल्प (रों) सेट से पूछ रहे हैं set
आदेश (के रूप में द्वारा करने का विकल्प (रों) सेट का विरोध shopt
आदेश)। आप इस स्ट्रिंग को एक चर में असाइन कर सकते हैं, और प्रारंभिक स्थिति को पुनर्स्थापित करने के लिए अपनी स्क्रिप्ट के अंत में चर को निष्पादित कर सकते हैं।
# 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"
यह समाधान एक साथ कई विकल्पों के लिए काम करता है:
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"
जोड़ने set +vx
से बचा जाता है विकल्प की एक लंबी सूची का मुद्रण।
और, यदि आप कोई विकल्प नाम सूचीबद्ध नहीं करते हैं,
oldstate="$(shopt -po)"
यह आपको सभी विकल्पों का मान देता है। और, यदि आप o
ध्वज छोड़ते हैं, तो आप shopt
विकल्पों के साथ भी ऐसा कर सकते हैं :
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
यदि आपको यह जांचने की आवश्यकता है कि क्या कोई set
विकल्प निर्धारित किया गया है, तो यह करने के लिए सबसे मुहावरेदार (बाश) तरीका है:
[[ -o xtrace ]]
जो अन्य दो समान परीक्षणों से बेहतर है:
[[ $- =~ x ]]
[[ $- == *x* ]]
किसी भी परीक्षण के साथ, यह काम करता है:
# 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"
एक shopt
विकल्प की स्थिति का परीक्षण कैसे करें :
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
सभी set
विकल्पों को संग्रहीत करने के लिए एक सरल, POSIX- संगत समाधान है:
set +o
जिसे पोसिक्स मानक में वर्णित किया गया है :
+ ओ
एक मानक विकल्प में वर्तमान आउटपुट सेटिंग्स को मानक आउटपुट में लिखें जो शेल के लिए पुन: उत्पन्न करने के लिए उपयुक्त है जो कमांड के समान विकल्प सेटिंग्स को प्राप्त करते हैं।
तो, बस:
oldstate=$(set +o)
set
कमांड का उपयोग करके निर्धारित सभी विकल्पों के लिए मानों को संरक्षित करेगा ।
फिर से, उनके मूल मानों के विकल्पों को पुनर्स्थापित करना चर को निष्पादित करने का विषय है:
set +vx; eval "$oldstate"
यह बैश के उपयोग के बराबर है shopt -po
। ध्यान दें कि यह सभी संभावित बैश विकल्पों को कवर नहीं करेगा , जैसा कि उनमें से कुछ द्वारा निर्धारित किया गया है ।shopt
shopt
बाश में सूचीबद्ध कई अन्य शैल विकल्प हैं :
$ 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
जिन्हें ऊपर सेट किए गए वैरिएबल से जोड़ा जा सकता है और उसी तरह से बहाल किया जा सकता है:
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
यह करना संभव है (यह $-
सुनिश्चित करने के लिए जोड़ा जाता है कि errexit
संरक्षित है):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
नोट : प्रत्येक शेल में सेट या अनसेट (विकल्पों में उल्लिखित विभिन्न विकल्पों का उल्लेख नहीं करने के लिए) की सूची बनाने के लिए थोड़ा अलग तरीका है, इसलिए स्ट्रिंग्स शेल के बीच पोर्टेबल नहीं हैं, लेकिन समान शेल के लिए मान्य हैं।
zsh
5.3 संस्करण के बाद से भी (POSIX के बाद) सही ढंग से काम करता है। पिछले संस्करणों में यह केवल आंशिक रूप से पॉसिक्स का अनुसरण करता set +o
था जिसमें यह एक प्रारूप में विकल्पों को मुद्रित करता था जो कमांड के रूप में शेल के लिए पुन: विवाद के लिए उपयुक्त था, लेकिन केवल सेट विकल्पों के लिए (यह अन-सेट विकल्पों को प्रिंट नहीं करता था )।
Mksh (और परिणाम lksh द्वारा) अभी तक (MIRBSD KSH R54 2016/11/11) ऐसा करने में सक्षम नहीं है। Mksh मैनुअल में यह शामिल है:
भविष्य के संस्करण में, सेट + ओ वर्तमान विकल्पों को पुनर्स्थापित करने के लिए पॉसिक्स अनुरूप और प्रिंट कमांड का व्यवहार करेगा।
बाश में, set -e
( errexit
) का मूल्य उप-गोले के अंदर रीसेट किया जाता है, जिससे set +o
एक $ (…) उप-खोल के साथ इसके मूल्य को पकड़ना मुश्किल हो जाता है।
वर्कअराउंड के रूप में, उपयोग करें:
oldstate="$(set +o); set -$-"
अल्मक्विस्ट शेल और डेरिवेटिव के साथ ( dash
,, नेटबीएसडी / फ्रीबीएसडी sh
कम से कम) और bash
4.4 या इसके बाद के संस्करण के साथ, आप एक फ़ंक्शन के साथ विकल्प को स्थानीय बना सकते हैं local -
( $-
यदि आपको पसंद है तो चर को स्थानीय बनाएं ):
$ bash-4.4 -c 'f() { local -; set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
यही कारण है कि पर लागू नहीं होता sourced फ़ाइलें, लेकिन आप को फिर से परिभाषित कर सकते हैं source
के रूप में source() { . "$@"; }
है कि चारों ओर काम करने के लिए।
साथ ksh88
, विकल्प परिवर्तन डिफ़ॉल्ट रूप से कार्य करने के लिए स्थानीय कर रहे हैं। इसके साथ ksh93
, function f { ...; }
सिंटैक्स के साथ परिभाषित कार्यों के लिए केवल यही मामला है (और स्कोप ksh88 सहित अन्य गोले में उपयोग किए जाने वाले गतिशील स्कूपिंग की तुलना में स्थिर है):
$ ksh93 -c 'function f { set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
में zsh
, यह localoptions
विकल्प के साथ किया गया है:
$ zsh -c 'f() { set -o localoptions; set -x; echo test; }; f; echo no trace'
+f:0> echo test
test
no trace
POSIXly, आप कर सकते हैं:
case $- in
(*x*) restore=;;
(*) restore='set +x'; set -x
esac
echo test
{ eval "$restore";} 2> /dev/null
echo no trace
हालाँकि कुछ गोले + 2> /dev/null
पुनर्स्थापना पर उत्पादन करेंगे (और यदि आप पहले से सक्षम हैं तो निश्चित रूप से उस निर्माण के निशान को देखेंगे )। वह दृष्टिकोण भी फिर से प्रवेश नहीं करता है (जैसे कि यदि आप किसी फ़ंक्शन में ऐसा करते हैं जो स्वयं या किसी अन्य फ़ंक्शन को कॉल करता है जो उसी चाल का उपयोग करता है)।case
set -x
देखें https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh कैसे एक ढेर है कि चारों ओर है कि काम करता है को लागू करने के लिए (चर और POSIX गोले के लिए विकल्प के लिए स्थानीय क्षेत्र)।
किसी भी शेल के साथ, आप विकल्पों के दायरे को सीमित करने के लिए उप-श्रेणियों का उपयोग कर सकते हैं
$ sh -c 'f() (set -x; echo test); f; echo no trace'
+ echo test
test
no trace
हालांकि, वह सब कुछ (चर, कार्य, उपनाम, पुनर्निर्देशन, वर्तमान कार्य निर्देशिका ...) के दायरे को सीमित करता है, न कि केवल विकल्प।
oldstate=$(set +o)
सभी विकल्पों को संग्रहीत करने का एक सरल (और POSIX) तरीका है।
pdksh
/ mksh
(और अन्य pdksh डेरिवेटिव) या zsh
जहां set +o
केवल डिफ़ॉल्ट सेटिंग्स से विचलन को आउटपुट करता है। यह बैश / डैश / यश के लिए काम करेगा लेकिन पोर्टेबल नहीं होगा।
आप $-
शुरुआत में चर को देख सकते हैं कि क्या -x
सेट किया गया है या नहीं और फिर इसे एक चर जैसे उदाहरण में सहेजें
if [[ $- == *x* ]]; then
was_x_set=1
else
was_x_set=0
fi
से बैश मैनुअल :
($ -, एक हाइफ़न।) मौजूदा विकल्प झंडे के लिए विस्तार के रूप में, आह्वान पर, सेट बिलिन कमांड या शेल द्वारा स्वयं निर्धारित किए गए (जैसे -i विकल्प) के रूप में फैलता है।
[[ $SHELLOPTS =~ xtrace ]] && wasset=1
set -x
echo rest of your script
[[ $wasset -eq 0 ]] && set +x
बैश में, $ SHELLOPTS को उन झंडों के साथ सेट किया जाता है जिन्हें चालू किया जाता है। इससे पहले कि आप xtrace को ऑन करें, और पहले से बंद होने पर ही xtrace को रीसेट करें।
बस स्पष्ट रूप से बताने के लिए, यदि set -x
स्क्रिप्ट की अवधि के लिए प्रभावी होना है, और यह सिर्फ एक अस्थायी परीक्षण उपाय है (स्थायी रूप से उत्पादन का हिस्सा नहीं होना है), तो या तो स्क्रिप्ट w / -x
विकल्प का आह्वान करें , जैसे,
$ bash -x path_to_script.sh
... या, -x
विकल्प को जोड़कर डीबग आउटपुट को सक्षम करने के लिए स्क्रिप्ट (पहली पंक्ति) को अस्थायी रूप से बदलें :
#!/bin/bash -x
...rest of script...
मुझे एहसास है कि आप जो चाहते हैं उसके लिए शायद यह बहुत व्यापक है, लेकिन यह अस्थायी रूप से स्क्रिप्ट के साथ जटिल किए बिना / अक्षम करने का सबसे सरल और तेज तरीका है, जिसे आप शायद वैसे भी निकालना चाहते हैं (मेरे अनुभव में)।
यह POSIX $-
विशेष पैरामीटर के माध्यम से दिखाई देने वाले झंडे को बचाने और पुनर्स्थापित करने के लिए कार्य प्रदान करता है । हम local
स्थानीय चरों के लिए एक्सटेंशन का उपयोग करते हैं । पोर्टेबल स्क्रिप्ट के अनुरूप POSIX में, वैश्विक चर का उपयोग किया जाएगा (कोई local
कीवर्ड नहीं ):
save_opts()
{
echo $-
}
restore_opts()
{
local saved=$1
local on
local off=$-
while [ ${#saved} -gt 0 ] ; do
local rest=${saved#?}
local first=${saved%$rest}
if echo $off | grep -q $first ; then
off=$(echo $off | tr -d $first)
fi
on="$on$first"
saved=$rest
done
set ${on+"-$on"} ${off+"+$off"}
}
इसका उपयोग इसी तरह से किया जाता है कि कैसे लिनक्स कर्नेल में झंडे को बचाया और पुनर्स्थापित किया जाता है:
Shell: Kernel:
flags=$(save_opts) long flags;
save_flags (flags);
set -x # or any other local_irq_disable(); /* disable irqs on this core */
# ... -x enabled ... /* ... interrupts disabled ... */
restore_opts $flags restore_flags(flags);
# ... x restored ... /* ... interrupts restored ... */
यह किसी भी विस्तारित विकल्प के लिए काम नहीं करेगा जो कि $-
चर में शामिल नहीं हैं ।
बस इस बात पर ध्यान दिया जाता है कि POSIX के पास वह चीज है जिसकी मैं तलाश कर रहा था: का +o
तर्क set
कोई विकल्प नहीं है, लेकिन एक कमांड जो कमांड का एक गुच्छा डंप करता है, अगर eval
-ed विकल्पों को पुनर्स्थापित करेगा। इसलिए:
flags=$(set +o)
set -x
# ...
eval "$flags"
बस।
एक छोटी समस्या यह है कि यदि -x
विकल्प को इससे पहले चालू किया जाता है eval
, तो set -o
आदेशों की एक बदसूरत हड़बड़ाहट देखी जाती है। इसे समाप्त करने के लिए, हम निम्नलिखित कार्य कर सकते हैं:
set +x # turn off trace not to see the flurry of set -o.
eval "$flags" # restore flags
आप एक उप-शेल का उपयोग कर सकते हैं।
(
set …
do stuff
)
Other stuff, that set does not apply to