बैश: `-x` गूंज से व्यक्तिगत लाइनों से बच


11

बैश में, जब -xविकल्प के साथ चल रहा है, तो क्या व्यक्तिगत आदेशों को गूंज से छूटना संभव है?

मैं जितना संभव हो उतना आउटपुट को साफ-सुथरा बनाने की कोशिश कर रहा हूं, इसलिए मैं अपनी स्क्रिप्ट के कुछ हिस्सों को एक सब-टाइम के साथ चला रहा हूं set +x। हालाँकि, पंक्ति set +xस्वयं अभी भी गूँजती है और आउटपुट में कोई मूल्यवान जानकारी नहीं जोड़ती है।

मुझे बुरे पुराने .batदिनों की याद है , जब दौड़ने के साथ echo on, व्यक्तिगत रेखाओं को ए से शुरू करके छूट दी जा सकती थी @। क्या बैश में कोई समकक्ष है?

#!/bin/bash -x

function i_know_what_this_does() {
  (
    set +x
    echo do stuff
  )
}

echo the next-next line still echoes 'set +x', is that avoidable?
i_know_what_this_does
echo and we are back and echoing is back on

ऊपर चलाते समय, आउटपुट है:

+ echo the next-next line still echoes 'set +x,' is that 'avoidable?'
the next-next line still echoes set +x, is that avoidable?
+ i_know_what_this_does
+ set +x
do stuff
+ echo and we are back and echoing is back on
and we are back and echoing is back on

जवाबों:


22

xtraceउत्पादन, stderr को जाता है ताकि आप अनुप्रेषित सकता stderrकरने के लिए /dev/null:

i_know_what_this_does() {
  echo do stuff
} 2> /dev/null

यदि आप अभी भी फ़ंक्शन के अंदर चलने वाले कमांड से त्रुटियों को देखना चाहते हैं, तो आप कर सकते हैं

i_know_what_this_does() (
  { set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
)

उस फ़ंक्शन के लिए एक उपधारा के माध्यम से स्थानीय गुंजाइश प्रदान करने के (...)बजाय उपयोग पर ध्यान दें {...}bash, संस्करण 4.4 अब समर्थन करता है, के बाद से local -समारोह (के समान करने के लिए स्थानीय विकल्प बनाने के लिए Almquist खोल में की तरह set -o localoptionsमें zsh) है, तो आप ऐसा करके subshell से बच सकते हैं:

i_know_what_this_does() {
  { local -; set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

bash4.0 से 4.3 के लिए एक विकल्प $BASH_XTRACEFDवैरिएबल का उपयोग करना होगा और उसके लिए एक समर्पित फाइल डिस्क्रिप्टर खुला होगा /dev/null:

exec 9> /dev/null
set -x
i_know_what_this_does() {
  { local BASH_XTRACEFD=9; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

चूँकि क्लोज़-ऑन-एक्ज़िक फ़्लैग के bashसाथ एक fd को चिह्नित करने की क्षमता का अभाव है, हालाँकि उस fd को अन्य कमांड्स पर लीक करने का दुष्प्रभाव है।

यह भी देखें इस locvar.sh जो लागू करने के लिए कुछ कार्यों में शामिल है स्थानीय और चर और POSIX लिपियों में कार्यों के लिए गुंजाइश भी साथ प्रदान करता है trace_fnऔर untrace_fnकार्यों के लिए उन्हें बनाने के लिए xtrace घ या नहीं।


मिठाई! मैं यह देखना चाह रहा था कि क्या कोई ऐसा मोडिफ़ायर है जिसे मैं फ़ंक्शन में ही लागू कर सकता हूं, लेकिन मैंने बस स्ट्रीडर को पुनर्निर्देशित करने के बारे में नहीं सोचा था। धन्यवाद!
क्लैके

1
Btw, एक ही पृष्ठ से stchaz.free.fr/which_interpreter बहुत भयानक और परेशान है। :-)
ताली

और अब मैं दूसरी विधि के लिए फिर से यहाँ वापस आया, सिलिंग सेट + x बिना सिलिंग के उपयोगी स्टेडर आउटपुट। एक बार फिर धन्यवाद!
क्लैक

2

जो कारण set +xमुद्रित किया गया है, उसका set -xअर्थ है कि "कमांड को चलाने के बारे में, जो विस्तार से, चलाने से पहले आप प्रिंट करने वाले हैं । तो शेल को यह नहीं पता है कि आप चाहते हैं कि यह चीजों को तब तक प्रिंट न करें जब तक कि यह लाइन को प्रिंट न कर दे। चीजों को मुद्रित करने के लिए। मेरी जानकारी के अनुसार, ऐसा होने से रोकने का कोई तरीका नहीं है।


0

यहां वह समाधान है जिसकी आप तलाश कर रहे हैं:

function xtrace() {
  # Print the line as if xtrace was turned on, using perl to filter out
  # the extra colon character and the following "set +x" line.
  (
    set -x
    # Colon is a no-op in bash, so nothing will execute.
    : "$@"
    set +x
  ) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2
  # Execute the original line unmolested
  "$@"
}

मूल कमांड एक पहचान परिवर्तन के तहत एक ही शेल में निष्पादित होता है। बस चलाने से पहले, आपको तर्कों का गैर-पुनरावर्ती पाठ प्राप्त होता है। यह आपको हर "इको" कमांड की डुप्लिकेट प्रतियों के साथ स्टैडर को बिना स्पैम किए परवाह किए हुए आदेशों को प्राप्त करने की अनुमति देता है।

# Example
echo "About to do something complicated ..."
xtrace do_something_complicated

या perl(और बहु-लाइन कमांड के साथ समस्याओं) से बचने के लिए :+() { :;} 2> /dev/null; xtrace() { (PS4=; set -x; + "$@";{ set +x; } 2> /dev/null); "$@";}
स्टीफन चेज़लस

नहीं, क्षमा करें, unix.stackexchange.com/a/60049/17980 वह समाधान है जिसकी मुझे तलाश थी। :-) क्या set -xयुद्धाभ्यास मुझे बस की तुलना में कुछ भी खरीदते हैं printf >&2 '+ %s\n' "$*"?
क्लैक

जैसे:xtrace() { printf >&2 '+ %s\n' "$*"; "$@"; }
१०:१५
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.