दिलचस्प पोस्ट
प्रिंटर जानकारी कैसे प्राप्त करें .नेट? कई डेटा.फ्रेम को एक डेटा.फ्रेम में एक लूप के साथ मिलाएं इंटरफेस, एकाधिक वंशानुक्रम बनाम इंटरफेस, इंटरफेस के लाभ का उपयोग क्यों करना है? कैसे सी # में एक फार्म से एक मूल्य वापस करने के लिए? रनटाइम पर वेब। कॉन्फिग ऐप सेटिंग्स को कैसे संशोधित करें? टुकड़ा और एडाप्टर के बीच अंतरफलक कैसे बनाऊँ? गतिशील रूप से फ़ील्ड में फ़ील्ड जोड़ें क्या "\ d" में regex एक अंक का मतलब है? टाइपस्क्रिप्ट में स्ट्रिंग मानों के साथ एक एन्यूम बनाएं php बहुआयामी सरणी डुप्लिकेट निकालते हैं उद्देश्य-सी: श्रेणी में संपत्ति / उदाहरण चर मैं सीएसवी फ़ाइल को आरडीडी में कैसे रूपांतरित कर सकता हूं कस्टम सूचना लेआउट और पाठ रंग UIViewContentModeScaleAspectFit और UIViewContentModeScaleToFill में अंतर? जब मैं एक न्यूल ऑब्जेक्ट पॉइंटर पर सदस्य फ़ंक्शन कॉल करता हूं, तो क्या होगा?

बैकअप स्क्रिप्ट के माध्यम से फ़ाइल को लॉग करने के लिए stdout की कॉपी पुनर्निर्देशित करें

मुझे पता है कि एक फाइल में stdout कैसे रीडायरेक्ट करें :

exec > foo.log echo test 

यह 'test' को foo.log फ़ाइल में डाल देगा।

अब मैं आउटपुट को लॉग फाइल में रीडायरेक्ट करना चाहता हूं और इसे stdout पर रखना चाहता हूं

अर्थात् यह स्क्रिप्ट के बाहर तुच्छ रूप से किया जा सकता है:

 script | tee foo.log 

लेकिन मैं इसे स्क्रिप्ट के भीतर ही घोषित करना चाहता हूं

मैंने कोशिश की

 exec | tee foo.log 

लेकिन यह काम नहीं कर रहा था

वेब के समाधान से एकत्रित समाधान "बैकअप स्क्रिप्ट के माध्यम से फ़ाइल को लॉग करने के लिए stdout की कॉपी पुनर्निर्देशित करें"

 #!/usr/bin/env bash # Redirect stdout ( > ) into a named pipe ( >() ) running "tee" exec > >(tee -i logfile.txt) # Without this, only stdout would be captured - ie your # log file would not contain any error messages. # SEE (and upvote) the answer by Adam Spiers, which keeps STDERR # as a separate stream - I did not want to steal from him by simply # adding his answer to mine. exec 2>&1 echo "foo" echo "bar" >&2 

ध्यान दें कि यह bash , sh नहीं है यदि आप स्क्रिप्ट sh myscript.sh साथ स्क्रिप्ट करते हैं, तो आपको syntax error near unexpected token '>' की तर्ज पर त्रुटि मिलेगी।

यदि आप सिग्नल ट्रैप्स के साथ काम कर रहे हैं, तो संकेत मिलने पर आप tee -i विकल्प का उपयोग करना चाहते हैं, यदि कोई संकेत होता है। (टिप्पणी के लिए जेम्स थॉमसमुं 1 9 7 9 के लिए धन्यवाद।)


उपकरण जो अपने पाइप या टर्मिनल (उदाहरण के लिए रंग और स्तंभयुक्त आउटपुट का उपयोग करते हुए ls ) को लिखते हैं, इस पर निर्भर करते हुए अपना आउटपुट बदलते हैं, ऊपर की रचना को पाइप के रूप में देखेंगे।

रंगाई / स्तंभकरण को लागू करने के विकल्प हैं (उदाहरण के लिए ls -C --color=always )। ध्यान दें कि इससे रंग कोड को लॉगफ़ाइल पर लिखा जा सकता है, जिससे इसे कम पठनीय बनाया जा सकता है।

स्वीकार किए गए उत्तर एसटीडीईआरआर को एक अलग फाइल डिस्क्रिप्टर के रूप में संरक्षित नहीं करता है। इसका मत

 ./script.sh >/dev/null 

टर्मिनल में आउटपुट bar नहीं होगा, केवल लॉगफ़ाइल के लिए, और

 ./script.sh 2>/dev/null 

टर्मिनल के लिए foo और bar दोनों आउटपुट करेगा। स्पष्ट रूप से ऐसा व्यवहार नहीं होता है जो सामान्य उपयोगकर्ता की उम्मीद की जाती है। यह दो अलग-अलग टी प्रक्रियाओं का उपयोग करके तय किया जा सकता है, जो एक ही लॉग फ़ाइल में संलग्न हैं:

 #!/bin/bash # See (and upvote) the comment by JamesThomasMoon1979 # explaining the use of the -i option to tee. exec > >(tee -ia foo.log) exec 2> >(tee -ia foo.log >&2) echo "foo" echo "bar" >&2 

(ध्यान दें कि उपरोक्त शुरूआत में लॉग फाइल को छोडना नहीं है – अगर आप चाहते हैं कि वह व्यवहार आपको जोड़ना चाहिए

 >foo.log 

स्क्रिप्ट के शीर्ष पर।)

टीओएस tee(1) POSIX.1-2008) की विनिर्देशन के लिए उत्पादन की आवश्यकता नहीं है, अर्थात् लाइन-बफ़र्ड भी नहीं, इसलिए इस मामले में यह संभव है कि foo.log और foo.log की एक ही पंक्ति पर समाप्त हो सके; हालांकि, यह टर्मिनल पर भी हो सकता है, इसलिए लॉग फ़ाइल टर्मिनल पर जो देखा जा सकता है उसका वफादार प्रतिबिंब होगा, यदि इसका सटीक दर्पण नहीं है। यदि आप एसटीडीओटी लाइनों को STDERR लाइन से अलग तरह से अलग करना चाहते हैं, तो दो लॉग फाइलों का उपयोग करने पर विचार करें, संभवतः बाद में कालानुक्रमिक पुन: संयोजन की अनुमति देने के लिए प्रत्येक पंक्ति पर तिथि स्टाम्प उपसर्गों के साथ।

बिजीबॉक्स और गैर-बाश गोले के लिए समाधान

स्वीकार किए जाते हैं उत्तर निश्चित रूप से बाश के लिए सबसे अच्छा विकल्प है। मैं एक बिज़बॉक्स वातावरण में काम कर रहा हूं, जो कि बैश की एक्सेस के बिना काम करता है, और यह exec > >(tee log.txt)exec > >(tee log.txt) सिंटैक्स को नहीं समझता है। यह exec >$PIPE ठीक से नहीं करता है, नामकरण पाइप के समान नाम से एक साधारण फाइल बनाने की कोशिश कर रहा है, जो विफल और लटका हुआ है

उम्मीद है कि यह किसी अन्य व्यक्ति के लिए उपयोगी होगा, जिसकी बाश नहीं है।

इसके अलावा, नामित किसी भी पाइप का उपयोग करने वाले के लिए, यह rm $PIPE लिए सुरक्षित है, क्योंकि वह वीएफएस से पाइप को अनलिंक करता है, लेकिन प्रक्रियाओं का उपयोग उस पर तब तक एक संदर्भ संख्या बनाए जब तक कि वह समाप्त न हो जाए।

ध्यान दें कि $ * का उपयोग जरूरी सुरक्षित नहीं है

 #!/bin/sh if [ "$SELF_LOGGING" != "1" ] then # The parent process will enter this branch and set up logging # Create a named piped for logging the child's output PIPE=tmp.fifo mkfifo $PIPE # Launch the child process without redirected to the named pipe SELF_LOGGING=1 sh $0 $* >$PIPE & # Save PID of child process PID=$! # Launch tee in a separate process tee logfile <$PIPE & # Unlink $PIPE because the parent process no longer needs it rm $PIPE # Wait for child process running the rest of this script wait $PID # Return the error code from the child process exit $? fi # The rest of the script goes here 

अपनी स्क्रिप्ट फाइल के अंदर, कोष्ठक के भीतर सभी आदेशों को इस तरह रखें:

 ( echo start ls -l echo end ) | tee foo.log 

Syslog में एक बाश स्क्रिप्ट लॉग बनाने का आसान तरीका स्क्रिप्ट आउटपुट /var/log/syslog माध्यम से और stderr के माध्यम से दोनों उपलब्ध है। syslog टाइमस्टैम्प सहित उपयोगी मेटाडाटा जोड़ देगा।

इस पंक्ति को शीर्ष पर जोड़ें:

 exec &> >(logger -t myscript -s) 

वैकल्पिक रूप से, लॉग को एक अलग फ़ाइल में भेजें:

 exec &> >(ts |tee -a /tmp/myscript.output >&2 ) 

इसके लिए अधिक आवश्यकता moreutils ( ts आदेश के लिए, जो टाइमस्टैंप जोड़ता है)

स्वीकार किए गए उत्तर का प्रयोग करके मेरी स्क्रिप्ट ने असाधारण रूप से जल्दी वापस कर दिया ('exec>> (टी …)' के बाद) पृष्ठभूमि में चलने वाली मेरी स्क्रिप्ट को छोड़कर। चूंकि मैं उस तरह से काम करने के लिए उस समाधान को प्राप्त नहीं कर पाया जिस तरह से मैं एक और हल पाया / समस्या के आसपास काम किया:

 # Logging setup logfile=mylogfile mkfifo ${logfile}.pipe tee < ${logfile}.pipe $logfile & exec &> ${logfile}.pipe rm ${logfile}.pipe # Rest of my script 

यह स्क्रिप्ट से आउटपुट प्रक्रिया से जाता है, पाइप के माध्यम से 'टी' की उप पृष्ठभूमि प्रक्रिया में जाता है जो सब कुछ डिस्क और स्क्रिप्ट के मूल स्टडआउट लॉग करता है।

ध्यान दें कि 'exec &>' दोनों stdout और stderr रीडायरेक्ट करते हैं, अगर हम चाहें तो हम उन्हें अलग-अलग रीडायरेक्ट कर सकते हैं या 'exec' में बदल सकते हैं अगर हम सिर्फ स्टडआउट चाहते हैं।

यहां तक ​​कि आप पाइप को स्क्रिप्ट की शुरुआत में फ़ाइल सिस्टम से निकाल दिया जाता है, जब तक यह प्रक्रिया समाप्त नहीं हो जाती है। हम इसे आरएम-लाइन के बाद फ़ाइल नाम के उपयोग से संदर्भ नहीं कर सकते

Bash 4 में एक coproc आदेश होता है जो एक कमांड में एक नामित पाइप स्थापित करता है और आपको इसके माध्यम से संवाद करने की अनुमति देता है।

इन में से कोई एक सही समाधान नहीं है, लेकिन यहां कुछ चीजें हैं जो आप कोशिश कर सकते हैं:

 exec >foo.log tail -f foo.log & # rest of your script 

या

 PIPE=tmp.fifo mkfifo $PIPE exec >$PIPE tee foo.log <$PIPE & # rest of your script rm $PIPE 

दूसरा, एक पाइप फ़ाइल को छोड़कर बैठेगा यदि कोई आपकी स्क्रिप्ट में गलत हो जाता है, जो कि या शायद एक समस्या न हो (यानी बाद में आप मूल rm इसे rm कर सकते हैं)।