इसे सेट किए बिना बैश सेट + एक्स


92

क्या किसी को पता है कि क्या हम set +xइसे छपाये बिना ही बैश में कह सकते हैं :

set -x
command
set +x

निशान

+ command
+ set +x

लेकिन यह सिर्फ प्रिंट होना चाहिए

+ command

बैश संस्करण 4.1.10 (4) है। यह मुझे पिछले कुछ समय से परेशान कर रहा है - आउटपुट बेकार set +xलाइनों से बंद है, जिससे ट्रेस सुविधा उतनी उपयोगी नहीं है जितनी यह हो सकती है।


यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन जब आप अपनी स्क्रिप्ट चलाते हैं तो क्यों नहीं:script.sh 2>&1 | grep -v 'set +x'
cdarke

जवाबों:


145

मेरे पास एक ही समस्या थी, और मैं एक समाधान खोजने में सक्षम था जो एक उपधारा का उपयोग नहीं करता है:

set -x
command
{ set +x; } 2>/dev/null

10
महान जवाब, सिर्फ एक नोट: कमांड के बाद अर्धविराम के बिना यह काम नहीं करेगा; और एक अर्धविराम के साथ लेकिन ब्रेसिज़ के लिए रिक्त स्थान के बिना, एक सिंटैक्स त्रुटि को उठाया जाएगा।
सादाऊ

9
यह निकास स्थिति को शून्य करता है।
गर्थ किड

8
@GarthKidd बाहर निकलने की स्थिति हर सफल कमांड के साथ शून्य है। set +xइस तरह की एक सफल कमान है
डैनियल एल्डर

3
ऐसे मामलों में जहां आपको बाहर निकलने की स्थिति की आवश्यकता होती है command, यह भिन्नता एक समाधान है { STATUS=$?; set +x; } 2>/dev/null:। फिर $STATUSअपने अवकाश पर बाद की पंक्तियों में निरीक्षण करें।
ग्रेग प्राइस

5
अलग रूप से, यहां एक संस्करण थोड़ा और आगे बढ़ा है { set +x; } 2>&-:। यह fd 2 को बंद करता है बजाए इसके कि इसे बिंदु / dev / null पर बनाया जाए। कुछ कार्यक्रम उस अच्छी तरह से नहीं संभालते हैं जब वे stderr पर प्रिंट करने की कोशिश करते हैं, यही वजह है कि सामान्य रूप से अच्छी शैली है / dev / null; लेकिन शेल का set -xअनुरेखण इसे ठीक तरह से संभालता है, इसलिए यह पूरी तरह से यहां काम करता है, और यह इस झुकाव को थोड़ा कम करता है।
ग्रेग प्राइस

43

आप एक उपधारा का उपयोग कर सकते हैं। सदस्यता से बाहर निकलने पर, सेटिंग xखो जाएगी:

( set -x ; command )

खैर, धन्यवाद ... अच्छी बात है। वास्तव में मैं "सब-शेल ट्रिक" से अवगत हूं। मुझे उम्मीद थी कि यह उससे भी आसान हो सकता है। इसमें कोड में पर्याप्त परिवर्तन, कोड को जटिल और कम पठनीय बनाना शामिल है। IMHO जो सेट + x लाइनों के साथ रहने से भी बदतर होगा ...
एंड्रियास स्पिंडलर

मैं नहीं देखता कि कैसे ( set -x \n command \n )किसी से भी बदतर है set -x \n command \n set +x
14

3
@chepner: आप चर सेट नहीं कर सकते।
कोरोबा

2
... और आप नहीं कर सकते cd: यह मूल निर्देशिका में वर्तमान निर्देशिका नहीं बदलता है।
एंड्रियास स्पिंडलर

क्षमा करें, मुझे यकीन नहीं है कि मुझे लगा कि आपकी वास्तविक आपत्ति क्या है। यह एक लंबा हफ्ता रहा है ...
chepner

8

मैंने हाल ही में इसका समाधान निकाला जब मैं इससे नाराज हो गया:

shopt -s expand_aliases
_xtrace() {
    case $1 in
        on) set -x ;;
        off) set +x ;;
    esac
}
alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'

यह आपको निम्नलिखित के रूप में xtrace को सक्षम और अक्षम करने की अनुमति देता है, जहां मैं लॉगिंग कर रहा हूं कि कैसे चर को तर्क दिए गए हैं:

xtrace on
ARG1=$1
ARG2=$2
xtrace off

और आपको आउटपुट मिलता है जो दिखता है:

$ ./script.sh one two
+ ARG1=one
+ ARG2=two

चतुर चाल (हालांकि आपको /dev/stdinभाग की आवश्यकता नहीं है )। चेतावनी यह है कि लिपियों में उर्फ ​​विस्तार को चालू करने से अवांछित दुष्प्रभाव हो सकते हैं।
mklement0

आप सही हे। मैंने अतिशयोक्ति को दूर करने के लिए उत्तर संपादित किया है /dev/stdin। मैं किसी भी विशिष्ट दुष्प्रभाव से अवगत नहीं हूं, क्योंकि गैर-संवादात्मक वातावरण में किसी भी फाइल को लोड नहीं करना चाहिए जो उपनामों को परिभाषित करता है। इसके क्या दुष्प्रभाव हो सकते हैं?
user108471

1
यह एक अच्छी बात है - मैं भूल गया कि उपनाम विरासत में नहीं हैं, इसलिए जोखिम जितना मैंने सोचा था उससे बहुत छोटा है (काल्पनिक रूप से, आपकी स्क्रिप्ट तीसरे पक्ष के कोड को सोर्स कर सकती है जो उपनामों को परिभाषित करने के लिए होता है, लेकिन मैं मानता हूं कि शायद यह वास्तविक नहीं है- दुनिया की चिंता)। +1
mklement0

1
@AndreasSpindler क्या आप इस बारे में विस्तार से बता सकते हैं कि आपको क्यों लगता है कि इस तकनीक से अधिक संवेदनशील जानकारी लीक होने की संभावना है?
user108471

1
... मूल रूप से क्योंकि उपनाम और कार्य उच्च-स्तरीय निर्माण हैं। set +xसमझौता करने के लिए बहुत कठिन (यदि असंभव नहीं है)। लेकिन यह अभी भी एक अच्छा और सीधा समाधान है - शायद अब तक का सबसे अच्छा।
एंड्रियास स्पिंडलर

7

कैसे एक समाधान के बारे में @ user108471 के सरलीकृत संस्करण पर आधारित है:

shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ set +x; } 2>/dev/null'

trace_on
...stuff...
trace_off

इस बारे में कैसा है? function () { set_plus_x='{ set +x; } 2>/dev/null' }
लक्सह

1

यह कुछ विचारों का एक संयोजन है जो कोड के ब्लॉक को संलग्न कर सकता है और निकास स्थिति को संरक्षित कर सकता है।

#!/bin/bash
shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ PREV_STATUS=$? ; set +x; } 2>/dev/null; (exit $PREV_STATUS)'

trace_on
echo hello
trace_off
echo "status: $?"

trace_on
(exit 56)
trace_off

जब निष्पादित:

$ ./test.sh 
+ echo hello
hello
status: 0
+ exit 56
status: 56


अच्छा प्रयास है, लेकिन मुझे लगता है कि ()चारों ओर exitआवश्यक नहीं। ठीक। हो सकता है कि के पागल है कि है, लेकिन अगर इस कोड को सामान्य रूप में प्रयोग किया जाता है कि तुम एक अच्छे हमले वेक्टर है: फिर से परिभाषित trace_onऔर trace_offऔर इंजेक्षन कोड कि निष्पादित आदेशों पढ़ता है। यदि आप अकेले ऐसे "उपयोग" का उपयोग करते हैं, तो यह शिक्षाप्रद है, लेकिन यदि कोड का उपयोग दूसरों के साथ किया जाता है, तो आपको यह विचार करना होगा कि क्या ऐसे गैर-मानकीकृत कार्यों के लाभ नुकसान से बाहर हैं। व्यक्तिगत { set +x; } 2>/dev/nullरूप से मैंने तय किया है क्योंकि यह निर्माण आमतौर पर समझा जाता है और इससे निकास की स्थिति भी नहीं बदलती है।
एंड्रियास स्पिंडलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.