2013-06-28 8 views
6

मैं एक शेल स्क्रिप्ट लिख रहा हूं जो कुछ मानों पर लूप करता है और प्रत्येक मान के लिए एक लंबी कमांड लाइन चलाता है। मैं इन आदेशों को रास्ते में प्रिंट करना चाहता हूं, जैसे make मेकफ़ाइल चलाते समय करता है। मुझे पता है कि मैं उन्हें चलाने से पहले सभी आदेशों को "गूंज" सकता हूं, लेकिन यह सुरुचिपूर्ण लगता है। इसलिए मैं बजाय set -x और इसी तरह के तंत्र में देख रहा हूँ:शैल स्क्रिप्ट में चुपचाप xt्रेस को कैसे निष्क्रिय करें?

#!/bin/sh 

for value in a long list of values 
do 
    set -v 
    touch $value # imagine a complicated invocation here 
    set +v 
done 

मेरे समस्या है: प्रत्येक यात्रा पर, न केवल interresting मुद्रित लाइन है, लेकिन यह भी set +x पंक्ति के रूप में अच्छी तरह से। क्या इसे रोकने के लिए किसी भी तरह से संभव है? यदि नहीं, तो आप किस कामकाज की सिफारिश करते हैं?

पीएस: उपरोक्त MWE sh का उपयोग करता है, लेकिन मेरे पास bash और zsh भी मदद करता है, जो मदद करता है।

+1

की संभावित डुप्लिकेट [बैश सेट + x के बिना यह मुद्रित किया जा रहा] (http://stackoverflow.com/questions/13195655/bash-set-x-without-it-being-printed) – Beetle

उत्तर

6

सैंडबॉक्स यह एक subshell में:

(set -x; do_thing_you_want_traced) 
बेशक

, चर या वातावरण है कि subshell में किए गए करने के लिए परिवर्तन गुम हो जाएंगे।

आप वास्तव में इस बारे में परवाह है, तो आप भी एक डीबग जाल का उपयोग करें (set -T का उपयोग कर पैदा करने के लिए यह काम करता है के द्वारा प्राप्त की जा करने के लिए) अपने स्वयं के set -x बराबर लागू करने के लिए कर सकता है।

उदाहरण के लिए, पार्टी का उपयोग कर यदि:

trap_fn() { 
    [[ $DEBUG && $BASH_COMMAND != "unset DEBUG" ]] && \ 
    printf "[%s:%s] %s\n" "$BASH_SOURCE" "$LINENO" "$BASH_COMMAND" 
    return 0 # do not block execution in extdebug mode 
} 
trap trap_fn DEBUG 

DEBUG=1 
# ...do something you want traced... 
unset DEBUG 

कहा यही कारण है, (एक डीबग जाल कर सकते हैं के रूप में) BASH_COMMAND उत्सर्जक set -x की पूरी तरह से बराबर नहीं है; उदाहरण के लिए, यह पोस्ट-विस्तार मूल्यों को प्रदर्शित नहीं करता है।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद! मैं आदेशों में चर के साथ नहीं खेल रहा हूं (वे वास्तव में केवल लंबे समय तक आक्रमण हैं) इसलिए मैं सबहेल दृष्टिकोण के लिए गया, और यह मेरी आवश्यकताओं को पूरी तरह से फिट करता है। – Gyom

+0

wooo, अच्छा विचार! :-) –

1

मैं

set -x >/dev/null 2>1; echo 1; echo 2; set +x >/dev/null 2>&1 

के बारे में सोचा, लेकिन मिल गया

+ echo 1 
1 
+ echo 2 
2 
+ 1> /dev/null 2>& 1 

मैं इन परिणामों से हैरान हूँ। .... लेकिन

set -x ; echo 1; echo 2; set +x 
+ echo 1 
1 
+ echo 2 
2 

आपकी आवश्यकता को पूरा करने के लिए देखता है।

मैं इसी तरह के परिणाम को देखा है जब मैं अपने ही लाइन पर प्रत्येक बयान डाल

IHTH (सेट + x छोड़कर)।

+0

FYI करें - 'set -x' आउटपुट केवल stderr पर जाता है, जब तक कि BASH_XTRACEFD में बैश में ओवरराइड नहीं किया जाता है 4. –

+0

... वैसे, माइलेज _indeed_ भिन्न होता है; मैं यहां 4.2.45 (1) बैश पर रिपोर्ट किए गए व्यवहार को पुन: उत्पन्न नहीं कर सकता। –

+0

@charlesDuffy: मैं ksh का उपयोग करता हूं, लेकिन मैंने हर समय बैश (यहां) के बारे में पढ़ा है। विवरण के लिए धन्यवाद! आप सभी को शुभकामनायें। – shellter

1

आप एक एकल लाइन xtrace को आजमाना चाह:

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. 
    : "[email protected]" 
    set +x 
) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2 
    # Execute the original line unmolested 
    "[email protected]" 
} 

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

# Example 
for value in $long_list; do 
    computed_value=$(echo "$value" | sed 's/.../...') 
    xtrace some_command -x -y -z $value $computed_value ... 
done 
संबंधित मुद्दे