2009-01-07 20 views
11

अभी मैंसंलग्न stderr करने के लिए पाठ बैश

exec 2>> ${errorLog} 

केवल नकारात्मक पक्ष के साथ एक त्रुटि लॉग में stderr रीडायरेक्ट करने के लिए कार्यकारी उपयोग कर रहा हूँ में पुनर्निर्देश मैं एक टाइमस्टैम्प के साथ प्रत्येक रन शुरू करने के लिए के बाद से कार्यकारी सिर्फ धक्का है कि है सीधे लॉग फ़ाइल में पाठ। क्या stderr को रीडायरेक्ट करने का कोई तरीका है लेकिन मुझे टेक्स्ट स्टैंप करने की अनुमति देता है, जैसे टाइम स्टैंप?

उत्तर

16

यह बहुत दिलचस्प है। मैं एक पुरुष जो बैश काफी अच्छी तरह से जानता है कहा है, और उसने मुझे इस तरह से कहा:

foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; }; 

सबसे पहले, कि एक समारोह stdin से कच्चे इनपुट की एक पंक्ति पढ़ने बनाता है, जबकि भारतीय विदेश सेवा के लिए काम नहीं करता है यह 'बनाता है टी रिक्त स्थान अनदेखा करें। एक पंक्ति को पढ़ने के बाद, यह उचित डेटा के साथ outputs।

exec 2> >(foo) 

आप जो कुछ भी stderr में लिखना अब foo समारोह के माध्यम से जाना होगा: तो फिर आपको लगता है कि समारोह में stderr रीडायरेक्ट करने के लिए पार्टी को बताने के लिए किया है। ध्यान दें कि जब आप एक इंटरैक्टिव खोल में यह करते हैं, आप शीघ्र अब और नहीं देख सकेंगे, क्योंकि यह stderr करने के लिए मुद्रित है, और foo में पढ़ने लाइन बफ़र है :)

+0

$ foo() {जबकि IFS = '' read -r लाइन; echo "$ (दिनांक) $ line" >> file.txt; किया हुआ; }; $ exec 2>> (foo) चेतावनी: प्रोग्राम '/ bin/bash' क्रैश हो गया। जोप्स – Peter

+0

लेकिन यदि मैं इसे बदलता हूं: echo 2 | टीई> (foo), तो यह ठीक काम करता है। – Peter

+0

प्रश्न में प्रत्येक पंक्ति पहले से खोले गए फ़ाइल में संलग्न हो जाती है। जवाब में प्रत्येक पंक्ति के लिए लॉग फ़ाइल खोला जाता है। और फ़ाइल के अंत की तलाश भी जरूरी है। 'Foo' में दूसरा 'exec' करना बेहतर हो सकता है। – ceving

1

आप सरल सिर्फ इस्तेमाल कर सकते हैं:

exec 1> >(sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1 

यह पूरी तरह से के बारे में तत्काल नहीं दिखाया (आईटीटी एक के बाद दिखाई देगा आपकी समस्या का समाधान नहीं होगा इस पोस्ट देखने के बाद, मैं एक और दृष्टिकोण है कि, होनहार लग रहा है भी देखा कम समय, लेकिन रीयलटाइम नहीं, क्योंकि पाइप कुछ डेटा कैश करेगा ...), लेकिन आउटपुट 1: 1 को stdout के साथ-साथ फ़ाइल में प्रदर्शित करेगा।

केवल समस्या यह है, कि मैं का समाधान नहीं कर सकता है, एक समारोह से ऐसा करने के लिए, के बाद से है कि एक subshell, जहां कार्यकारी मुख्य कार्यक्रम के लिए बेकार है खोलता है ...

+0

इस सभी लाइनों से एक ही समय टिकट मिलता है? – ceving

-1
cat q23123 2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
0

यह उदाहरण मूल stdout और stderr को खोए बिना stdout और stderr रीडायरेक्ट करता है। Stdout हैंडलर में त्रुटियां stderr हैंडलर पर लॉग इन हैं। फ़ाइल डिस्क्रिप्टर चर में सहेजे गए हैं और बाल प्रक्रियाओं में बंद हैं। बैश ख्याल रखता है, कि कोई टकराव नहीं होता है।

#! /bin/bash 

stamp() 
{ 
    local LINE 
    while IFS='' read -r LINE; do 
    echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $$ $LINE" 
    done 
} 

exec {STDOUT}>&1 
exec {STDERR}>&2 
exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp) 
exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp) 

for n in $(seq 3); do 
    echo loop $n >&$STDOUT 
    echo o$n 
    echo e$n >&2 
done 

यह एक वर्तमान बैश संस्करण लेकिन Shellshock एक करने के लिए धन्यवाद की आवश्यकता है आजकल इस पर भरोसा कर सकते हैं।

संबंधित मुद्दे