मानक आउटपुट को इंटर किए बिना लॉगफाइल में बैश -x आउटपुट भेजें


12

क्या किसी फ़ाइल को -x विकल्प के साथ बैश स्क्रिप्ट चलाकर प्रदर्शित की गई जानकारी भेजने का एक तरीका है, जबकि स्क्रिप्ट चलाने वाले उपयोगकर्ता द्वारा देखे गए मानक आउटपुट को नहीं बदलते हैं?

यह एक डिबगिंग फीचर है जिसे मैं एक बैश स्क्रिप्ट में लागू करना चाहूंगा जिसे हम बार-बार बदलते हैं।

बहुत सराहना की।

जवाबों:


21

-X से आउटपुट stderr पर जाता है, stdout में नहीं। लेकिन यहां तक ​​कि यह एक समस्या भी हो सकती है - बहुत सी लिपियों में stderr की सामग्री पर कार्यात्मक निर्भरता होगी, और डिबग और stderr धाराओं को कुछ मामलों में एक साथ मिश्रित करने के लिए इस तरह की गड़बड़ है।

बैश संस्करण> 4.1 एक अलग समाधान प्रदान करते हैं: BASH_XTRACEFD पर्यावरण चर आपको एक फ़ाइल विवरणक निर्दिष्ट करने की अनुमति देता है जिसका उपयोग डीबग स्ट्रीम भेजने के लिए किया जाएगा। यह एक फ़ाइल या पाइप या कोई अन्य यूनिक्स-वाई अच्छाई हो सकती है जो आपको पसंद है।

# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it  (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19

# turn on the debug stream:
set -x

# run some commands:
cd /etc
find 
echo "Well, that was fun."

# Close the output:
set +x
exec 19>&-

# See what we got:
cat /tmp/my-script.log

थोड़े और अधिक निपुणता के साथ, आप अन्य काम कर सकते हैं - जैसे कि स्टडआउट और / या स्टडिन स्ट्रीम्स पर 'टी' करना, और डिबग आउटपुट के साथ इंटरलेव करना, इसलिए आपका लॉग अधिक पूर्ण है। इस पर अधिक जानकारी के लिए, /programming/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself देखें

विकल्प पर इस दृष्टिकोण का बड़ा लाभ यह है कि आप डिबग आउटपुट को स्टडआउट या स्टडर में इंजेक्ट करके अपनी स्क्रिप्ट के व्यवहार में परिवर्तन नहीं कर रहे हैं।


फ़ाइल के लिए अप्रयुक्त फ़ाइल विवरणक खोजने के तरीके के बारे में भी यहाँ देखें ।
जर्नो

क्या फाइल डिस्क्रिप्टर (यानी लाइन exec 19>&-) को बंद करना आवश्यक है ? मेरे अनुभव में यह स्वचालित रूप से बंद हो जाता है, जब स्क्रिप्ट खत्म हो जाती है।
जर्नो

1
ऊपर दिखाया गया कोड यह नहीं मानता है कि आप एक स्क्रिप्ट चला रहे हैं, या स्क्रिप्ट कितनी लंबी हो सकती है, आदि। यह सच है कि अगर आप बस यह स्निपेट कर रहे हैं, और इसे स्क्रिप्ट में रखें, तो फ़ाइल हैंडल हो जाएगी केवल इसलिए खोल दिया जाए क्योंकि स्क्रिप्ट के अंत में पूरा शेल चला जाता है। तो उस उपयोग के मामले में, आपको कड़ाई से हैंडल को बंद करने की आवश्यकता नहीं है। लेकिन सामान्य तौर पर जब किसी संसाधन के खिलाफ कोडिंग की जाती है, तो आपने जो खोला है, उसे बंद करने के लिए यह एक अच्छा अभ्यास है, क्योंकि तब आपके कोड का उपयोग बड़े संदर्भ में किया जा सकता है, जहां हाउसकीपिंग की अधिक संभावना है।

आप BASH_XTRACEFD को क्यों निर्यात करते हैं? इसके लिए सिर्फ मूल्य क्यों नहीं निर्धारित किया जाए?
जारो

वैसे भी, फ़ाइल डिस्क्रिप्टर को बंद करने का एक वैकल्पिक तरीका BASH_XTRACEFD के लिए नया मान (उदा। नल) सेट करना है या इसे अनसेट करना है।
जरनू

4

set -xमानक आउटपुट में कुछ भी नहीं भेजता है, इसलिए वहां कोई समस्या नहीं है। यह जो करता है वह मानक त्रुटि को लिखता है, जो कि डिफ़ॉल्ट रूप से कंसोल पर जाता है।

आप क्या करना चाहते हैं, इस तरह से किसी अन्य फ़ाइल पर रीडायरेक्ट करना है:

/bin/sh -x /my/script/file 2>/my/log/file

1

देखते हैं man tee

आप इसे चलाते हैं tee commandname filenameऔर यह कमांड आउटपुट को प्रदर्शित करेगा stdoutऔर इसे भी लिखेगा filename

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.