2012-01-04 11 views
8

मैं वर्तमान में सब कुछ है कि टर्मिनल के लिए चला जाता है पर कब्जा औरबैश टी निकालने रंग

exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE) 

लेकिन एक लॉग फ़ाइल में फेंक करने के लिए निम्न का उपयोग कर रहा हूँ, मैं नहीं चाहता कि रंग मुक्ति कोड/अव्यवस्था में जा चाहते हैं लॉग फ़ाइल। तो मैं कुछ इस तरह कि sorta

exec 4<&1 5<&2 1>&2>&>(
    while read -u 0; do 
     #to terminal 
     echo "$REPLY" 
     #to log file (color removed) 
     echo "$REPLY" | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' >> $LOG_FILE 
    done 
    unset REPLY #tidy 
) 

काम करता है जो स्क्रिप्ट के कुछ भागों (जैसे echo -n "..." या printf\n के बिना) के लिए आदर्श नहीं है गाड़ी वापसी के लिए read प्रतीक्षा करता है को छोड़कर है।


जोनाथन Leffler की जवाब देने के लिए का पालन-अप:

उदाहरण स्क्रिप्ट test.sh को देखते हुए:

#!/bin/bash 

LOG_FILE="./test.log" 
echo -n >$LOG_FILE 

exec 4<&1 5<&2 1>&2>&>(tee -a >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > $LOG_FILE)) 


##### ##### ##### 
# Main 

echo "starting execution" 
printf "\n\n" 

echo "color test:" 
echo -e "\033[0;31mhello \033[0;32mworld\033[0m!" 
printf "\n\n" 

echo -e "\033[0;36mEnvironment:\033[0m\n foo: cat\n bar: dog\n your wife: hot\n fix: A/C" 
echo -n "Before we get started. Is the above information correct? " 
read YES 
echo -e "\n[READ] $YES" >> $LOG_FILE 
YES=$(echo "$YES" | sed 's/^\s*//;s/\s*$//') 
test ! "$(echo "$YES" | grep -iE '^y(es)?$')" && echo -e "\nExiting... :(" && exit 
printf "\n\n" 

#...some hundreds of lines of code later... 

echo "Done!" 


##### ##### ##### 
# End 

exec 1<&4 4>&- 2<&5 5>&- 

echo "Log File: $LOG_FILE" 
  1. टर्मिनल के लिए उत्पादन की उम्मीद के रूप में किया जाता है और वहाँ कोई रंग मुक्ति कोड है वांछित के रूप में लॉग फ़ाइल में अव्यवस्था। हालांकि test.log की जांच करने पर, मुझे [READ] ... नहीं दिखाई देता है (test.sh की लाइन 21 देखें)।

  2. लॉग फ़ाइल [मेरी वास्तविक बैश स्क्रिप्ट के] में 4 और 5 एफडीएस बंद करने के बाद भी इसके अंत में Log File: ... लाइन है। मैं दूसरे exec से पहले sleep 1 डालकर इस मुद्दे को हल करने में सक्षम था - मुझे लगता है कि इसके लिए एक रेस हालत या एफडी शेंगेनिन्स दोष है। दुर्भाग्य से आप लोगों के लिए, मैं इस समस्या को test.sh के साथ पुन: उत्पन्न करने में सक्षम नहीं हूं लेकिन मुझे किसी भी अटकलें में दिलचस्पी होगी।

+0

ध्यान दें कि \ e [... एम कोड VT100/VT200/आदि के लिए विशिष्ट हैं। और वास्तव में प्रोग्राम द्वारा एक अलग प्रकार के $ TERM पर आउटपुट नहीं किया जा सकता है। –

उत्तर

3

pee कार्यक्रम Is it possible to distribute stdin over parallel processes में चर्चा उपयोग पर विचार करें। वास्तविक आउटपुट में रंग भेजने के दौरान, यह आपको अपने sed स्क्रिप्ट के माध्यम से लॉग डेटा भेजने की अनुमति देगा।

इसका एक बड़ा फायदा यह है कि यह 'लॉग आउटपुट की प्रति पंक्ति एक बार' sed निष्पादित करेगा '; यह प्रदर्शन के लिए वास्तव में शैक्षिक है (निष्पादित प्रक्रियाओं की संख्या के मामले में, यदि कुछ और नहीं है)।

+0

उत्कृष्ट! धन्यवाद! 'exec 4 <&1 5<&2 1> और 2> &> (tee -a> (sed -r's/\ x1B \ [([0-9] {1,2} (; [0-9] {1,2})?) ? [एम | के] // जी '> $ LOG_FILE)) ' – Andrew

+0

कृपया मेरा अनुवर्ती देखें – Andrew

1

मैं जानता हूँ कि यह एक पूर्ण समाधान नहीं है, लेकिन cat -v गैर दिखाई वर्ण कर देगा की तरह \x1B^[[1;34m की तरह दिखाई दे रूप में परिवर्तित किया जाना है। आउटपुट गन्दा हो जाएगा, लेकिन यह कम से कम ascii पाठ होगा।

0

आप पढ़ने के लिए -n विकल्प का उपयोग करने का प्रयास कर सकते हैं। यह एक नई लाइन के इंतजार के बजाय एन पात्रों में पढ़ता है। आप इसे एक पर सेट कर सकते हैं। यह कोड चलाने के पुनरावृत्ति की संख्या में वृद्धि करेगा, लेकिन यह न्यूलाइन के लिए इंतजार नहीं करेगा।

आदमी से:

-n NCHARS read returns after reading NCHARS characters rather than waiting for a complete line of input.

नोट: मैं परीक्षण नहीं किया इस

0

मैं अपने आदेश को चलाने से पहले TERM=dumb की स्थापना द्वारा इस तरह काम करना का उपयोग करें देखें। उस टैब, सीआर और एलएफ को छोड़कर किसी भी नियंत्रण वर्ण को बहुत हटा दिया गया। मुझे नहीं पता कि यह आपकी स्थिति के लिए काम करता है, लेकिन यह एक कोशिश के लायक है। समस्या यह है कि आप अपने टर्मिनल पर रंग एन्कोडिंग नहीं देख पाएंगे क्योंकि यह एक गूंगा टर्मिनल है।

तुम भी या तो vis या cat (विशेष रूप से -v पैरामीटर) कोशिश करते हैं और अगर इन आपके लिए कुछ कर देख सकते हैं। आप बस इस तरह से अपनी पाइपलाइन में डाल चाहते हैं:

exec 4<&1 5<&2 1>&2>&>(tee -a | cat -v | $LOG_FILE) 

वैसे, लगभग सभी टर्मिनल कार्यक्रमों इनपुट पर कब्जा करने का विकल्प होता है, और सबसे यह साफ आप के लिए। आप किस मंच पर हैं, और आप किस प्रकार का टर्मिनल प्रोग्राम उपयोग कर रहे हैं?

0

screen -L या script आदेश इस निष्पादन लूप के बजाय व्यवहार्य विकल्प हो सकते हैं?

+0

क्या हम' स्क्रीन 'के साथ नियंत्रण वर्ण बंद कर सकते हैं? – Stuart