सवाल बैश: लाल रंग में मुद्रित stderr


बैश डिस्प्ले बनाने का कोई तरीका है stderr लाल रंग में संदेश?


97
2017-08-26 21:10


मूल


मुझे लगता है कि बैश कभी भी अपने आउटपुट को रंगीन नहीं करेगा: कुछ प्रोग्राम कुछ पार्स करना चाहते हैं, और रंगीन भाग से बचने वाले दृश्यों के साथ डेटा खराब हो जाएगा। एक जीयूआई ऐप रंगों को संभालना चाहिए, मुझे लगता है। - kolypto
बालाज़ पॉज़सर और killdash9 का मिश्रण कुरकुरा देता है: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }  बैश और zsh के लिए काम करता है। इसे उत्तर बी / सी प्रतिष्ठा के रूप में नहीं जोड़ा जा सकता है। - Heinrich Hartmann
मैं ऐसे उत्तर की प्रतीक्षा कर रहा हूं जो ऐसा करने के लिए बाश को संशोधित करता है। सभी के नीचे समाधान वास्तव में stderr संशोधित करें और संभवतः इसे फिर से व्यवस्थित करें w.r.t. stdout जो चीजों को तोड़ता है जब stderr के सटीक बाइट अनुक्रम संरक्षित किया जाना चाहिए उदा। जब पाइपिंग। - masterxilo


जवाब:


command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)

84
2017-08-26 21:39



महान! लेकिन मुझे आश्चर्य है कि इसे स्थायी बनाने का कोई तरीका है :) - kolypto
महान टिप! सुझाव: जोड़कर >&2 ठीक पहले ; done), stderr के लिए इरादा उत्पादन वास्तव में stderr के लिए लिखा है। यह उपयोगी है अगर आप प्रोग्राम के सामान्य आउटपुट को कैप्चर करना चाहते हैं। - henko
निम्नलिखित उपयोग करता है tput, और मेरी राय में थोड़ा और पठनीय है: command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done) - Stefan Lasiewski
मुझे लगता है कि प्रत्येक आउटपुट लाइन के लिए 2 ट्यूट प्रक्रियाओं को निष्पादित करना बिल्कुल सुरुचिपूर्ण नहीं है। हो सकता है कि आप एक चर में tput आदेशों के आउटपुट को संग्रहीत करेंगे और प्रत्येक गूंज के लिए उपयोग करें। लेकिन फिर, पठनीयता वास्तव में बेहतर नहीं है। - Balázs Pozsár
यह समाधान व्हाइटस्पेस को संरक्षित नहीं करता है लेकिन मुझे इसकी शराब के लिए पसंद है। IFS= read -r line मदद करनी चाहिए लेकिन नहीं। यकीन नहीं है कि क्यों। - Max Murphy


विधि 1: प्रक्रिया प्रतिस्थापन का उपयोग करें:

command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)

विधि 2: बैश स्क्रिप्ट में कोई फ़ंक्शन बनाएं:

color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1

इसे इस तरह प्रयोग करें:

$ color command

दोनों विधियां कमांड दिखाएंगी stderr लाल में।

विधि 2 कैसे काम करता है इसकी व्याख्या के लिए पढ़ना जारी रखें। इस आदेश द्वारा प्रदर्शित कुछ रोचक विशेषताएं हैं।

  • color()... - रंग नामक एक बैश समारोह बनाता है।
  • set -o pipefail - यह एक शेल विकल्प है जो एक कमांड के त्रुटि रिटर्न कोड को संरक्षित करता है जिसका आउटपुट किसी अन्य कमांड में पाइप किया जाता है। यह एक सबहेल में किया जाता है, जो कोष्ठक द्वारा बनाया जाता है, ताकि बाहरी शेल में पाइपफेल विकल्प न बदल सके।
  • "$@" - फ़ंक्शन को तर्कों को एक नए कमांड के रूप में निष्पादित करता है। "$@" के बराबर है "$1" "$2" ...
  • 2>&1 - रीडायरेक्ट करता है stderr आदेश के लिए stdout ताकि यह हो जाए sedकी stdin
  • >&3 - के लिए शॉर्टैंड 1>&3, यह रीडायरेक्ट करता है stdout एक नई अस्थायी फ़ाइल वर्णनकर्ता के लिए 33 वापस घुमाया जाता है stdout बाद में।
  • sed ... - उपरोक्त रीडायरेक्ट के कारण, sedकी stdin है stderr निष्पादित आदेश का। इसका कार्य रंग कोड के साथ प्रत्येक पंक्ति को घेरना है।
  • $'...' एक बैश निर्माण जो इसे बैकस्लैश-बच निकले वर्णों को समझने का कारण बनता है
  • .* - पूरी लाइन से मेल खाता है।
  • \e[31m - एएनएसआई एस्केप अनुक्रम जो निम्न वर्णों को लाल होने का कारण बनता है
  • & - द sed चरित्र को प्रतिस्थापित करें जो पूरे मिलान वाली स्ट्रिंग (इस मामले में पूरी पंक्ति) तक फैलता है।
  • \e[m - एएनएसआई एस्केप अनुक्रम जो रंग को रीसेट करता है।
  • >&2 - के लिए शॉर्टैंड 1>&2, यह रीडायरेक्ट करता है sedकी stdout सेवा मेरे stderr
  • 3>&1 - अस्थायी फ़ाइल वर्णनकर्ता को पुनर्निर्देशित करता है 3 में वापस stdout

72
2018-04-23 20:53



+1 सबसे अच्छा जवाब! पूरी तरह से अंडररेड! - muhqu
महान जवाब और यहां तक ​​कि बेहतर स्पष्टीकरण - Daniel Serodio
आपको सभी अतिरिक्त पुनर्निर्देशन करने की आवश्यकता क्यों है? ओवरकिल की तरह लगता है - qodeninja
@qodeninja स्पष्टीकरण पुनर्निर्देशन के लिए उद्देश्य देता है। यदि आप इसे करने का एक आसान तरीका ढूंढ सकते हैं, तो मुझे इसे देखना अच्छा लगेगा! - killdash9
क्या इसमें काम करने का कोई तरीका है zsh? - Eyal Levin


आप stderred भी देख सकते हैं: https://github.com/sickill/stderred


23
2017-12-13 21:40



वाह, यह उपयोगिता बहुत बढ़िया है, केवल एक चीज जिसकी आवश्यकता होगी वह एक उपयुक्त भंडार है जो इसे सभी उपयोगकर्ताओं के लिए स्थापित करता है, एक पंक्ति के साथ, इसे सक्षम करने के लिए और अधिक काम नहीं करना पड़ता है। - sorin
जब मैंने इसे एक अलग टर्मिनल में एक बिल्ड स्क्रिप्ट के साथ परीक्षण किया, तो अच्छी तरह से काम करने के लिए माना जाता है, लेकिन मैं इसे वैश्विक रूप से उपयोग करने में संकोच करता हूं (में .bashrc)। हालांकि धन्यवाद! - Joel Purra
ओएस एक्स एल कैपिटन में, जिस तरह से यह काम करता है (DYLD_INSERT_LIBRARIES) सिस्टम बाइनरी में "टूटा हुआ" है क्योंकि वे एसआईपी द्वारा संरक्षित हैं। इसलिए अन्य उत्तरों में दिए गए बैश विकल्पों का उपयोग करना बेहतर हो सकता है। - hmijail
मैकोज़ के लिए @hmijail कृपया पालन करें github.com/sickill/stderred/issues/60 इसलिए हम एक कामकाज पा सकते हैं, आंशिक एक पहले से मौजूद है लेकिन थोड़ा सा छोटी है। - sorin


http://sourceforge.net/projects/hilite/


14
2017-08-26 21:18





बनाने का बैश तरीका stderr धाराओं को पुनर्निर्देशित करने के लिए स्थायी रूप से लाल 'exec' का उपयोग कर रहा है। अपने bashrc में निम्नलिखित जोड़ें:

exec 9>&2
exec 8> >(
    while IFS='' read -r line || [ -n "$line" ]; do
       echo -e "\033[31m${line}\033[0m"
    done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'

मैंने पहले इस पर पोस्ट किया है: एसटीडीओयूटी और एसटीडीईआरआर के लिए फ़ॉन्ट रंग कैसे सेट करें


11
2018-01-29 08:49



सम्बंधित: unix.stackexchange.com/questions/367636/... - Blauhirn
यह अब तक का सबसे अच्छा जवाब है; स्थापना के बिना कार्यान्वित करना आसान / सुडो विशेषाधिकार की आवश्यकता है, और सभी आदेशों के लिए सामान्यीकृत किया जा सकता है। - Luke Davis
दुर्भाग्यवश यह कमांड चेनिंग (कमांड और एंड कॉमांड || errorHandlerCommand) के साथ अच्छी तरह से नहीं खेलता है। एरर आउटपुट त्रुटि के बाद जाता है हैंडलर कमांड आउटपुट। - carlin.scott
इसी तरह, अगर मैं source ~/.bashrc इसके साथ दो बार, मेरा टर्मिनल मूल रूप से ताला लगा देता है। - Dolph
@ डॉल्फ: मेरे bashrc में मैं इस कोड को पुनः लोड करने से रोकने के लिए आस-पास के बयान के साथ आसानी से इसके खिलाफ सुरक्षा करता हूं। अन्यथा, पुनर्निर्देशन पहले से ही हो जाने के बाद समस्या निवारण 'निष्पादन 9> और 2' है। यदि आप जानते हैं कि> 2 मूल रूप से इंगित कर रहा है तो शायद इसे स्थिर में बदलें। - gospes


मैंने एक रैपर स्क्रिप्ट बनाई है जो शुद्ध बैश में बालाज़ पॉज़सर के जवाब को लागू करता है। अपने आउटपुट को रंगीन करने के लिए इसे अपने $ PATH और उपसर्ग आदेशों में सहेजें।


    #! / Bin / bash

    अगर [$ 1 == "--help"]; फिर
        गूंज "एक आदेश निष्पादित करता है और सभी त्रुटियों का रंगीन होता है"
        गूंजें "उदाहरण:` बेसनाम $ {0} 'wget ... "
        गूंज "(सी) o_O Tync, आईसीक्यू # 1227-700, आनंद लें!"
        बाहर निकलें 0
        फाई

    # सभी त्रुटियों को पकड़ने के लिए Temp फ़ाइल
    TMP_ERRS = $ (mktemp)

    # आदेश निष्पादित करें
    "$ @" 2>> (पढ़ने के दौरान लाइन; echo -e "\ e [01; 31m $ line \ e [0m" | tee - $ TMP_ERRS करें; किया गया)
    EXIT_CODE = $?

    # सभी त्रुटियों को फिर से प्रदर्शित करें
    अगर [-एस "$ TMP_ERRS"]; फिर
        echo -e "\ n \ n \ n \ e [01; 31m === ERRORS === \ e [0m"
        बिल्ली $ TMP_ERRS
        फाई
    आरएम-एफ $ टीएमपी_ईआरआरएस

    # समाप्त
    $ EXIT_CODE से बाहर निकलें


7
2017-08-26 22:13



इसे "कुशल" बनाया जा सकता है अगर "| टीई ..." "किया" के बाद रखा गया था। - Juliano


आप इस तरह के एक समारोह का उपयोग कर सकते हैं


 #!/bin/sh

color() {
      printf '\033[%sm%s\033[m\n' "$@"
      # usage color "31;5" "string"
      # 0 default
      # 5 blink, 1 strong, 4 underlined
      # fg: 31 red,  32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
      # bg: 40 black, 41 red, 44 blue, 45 purple
      }
string="Hello world!"
color '31;1' "$string" >&2


3
2017-08-26 22:29



समस्या को संबोधित नहीं करते हैं। आपने stdr से stdr को अलग करने का एक तरीका प्रदान नहीं किया है, जो ओ.पी. में रूचि रखता है। - Jeremy Visser


मेरे पास O_o Tync की स्क्रिप्ट का थोड़ा संशोधित संस्करण है। मुझे ओएस एक्स शेर के लिए इन मोडों को बनाने की ज़रूरत है और यह सही नहीं है क्योंकि स्क्रिप्ट कभी-कभी लिपटे कमांड से पहले पूरा हो जाता है। मैंने नींद ली है लेकिन मुझे यकीन है कि एक बेहतर तरीका है।

#!/bin/bash

   if [ $1 == "--help" ] ; then
       echo "Executes a command and colorizes all errors occured"
       echo "Example: `basename ${0}` wget ..."
       echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!"
       exit 0
       fi

   # Temp file to catch all errors
   TMP_ERRS=`mktemp /tmp/temperr.XXXXXX` || exit 1

   # Execute command
   "$@" 2> >(while read line; do echo -e "$(tput setaf 1)$line\n" | tee -a $TMP_ERRS; done)
   EXIT_CODE=$?

   sleep 1
   # Display all errors again
   if [ -s "$TMP_ERRS" ] ; then
       echo -e "\n\n\n$(tput setaf 1) === ERRORS === "
       cat $TMP_ERRS
   else
       echo "No errors collected in $TMP_ERRS"
   fi
   rm -f $TMP_ERRS

   # Finish
   exit $EXIT_CODE

1
2018-06-08 17:37





यह समाधान मेरे लिए काम किया: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr

मैंने यह काम मेरे अंदर रखा है .bashrc या .zshrc:

# Red STDERR
# rse <command string>
function rse()
{
    # We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace
    # Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back
    ((eval $(for phrase in "$@"; do echo -n "'$phrase' "; done)) 3>&1 1>&2 2>&3 | sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/") 3>&1 1>&2 2>&3
}

फिर उदाहरण के लिए:

$ rse cat non_existing_file.txt

मुझे एक लाल आउटपुट देगा।


1
2017-08-25 09:16





एक संस्करण का उपयोग कर FIFOs

mkfifo errs
stdbuf -o0 -e0 -i0 grep . foo | while read line; do echo -e "\e[01;31m$line  \e[0m" >&2; done &
stdbuf -o0 -e0 -i0 sh $script 2>errs

0
2018-06-04 10:04





xargs और printf का उपयोग कर:

command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)

0
2017-08-23 13:37