बैश: लाल रंग में प्रिंटर


122

क्या लाल रंग में बैश प्रदर्शन स्टैडर संदेश बनाने का एक तरीका है ?


4
मुझे लगता है कि बैश कभी भी अपने आउटपुट को रंगीन नहीं करेगा: कुछ प्रोग्राम कुछ पार्स करना चाहते हैं, और रंग बदलना एस्केप दृश्यों के साथ डेटा को खराब कर देगा। एक GUI ऐप को रंगों को संभालना चाहिए, मुझे लगता है।
kolypto

Balázs Pozsár और Killdash9 के उत्तर का संयोजन कुरकुरा देता है: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') } बैश और zsh के लिए काम करता है। इसे उत्तर b / c प्रतिष्ठा के रूप में नहीं जोड़ा जा सकता।
हेनरिक हार्टमैन

1
मैं एक उत्तर की प्रतीक्षा कर रहा हूं जो ऐसा करने के लिए बैश को संशोधित करता है। सभी नीचे दिए गए समाधान वास्तव में stderr को संशोधित करते हैं और संभवत: इसे भी ret stdout में बदल देते हैं जो चीजों को तोड़ता है जब stderr के सटीक बाइट अनुक्रम को संरक्षित किया जाना चाहिए जैसे कि पाइपिंग करते समय।
मास्टरएक्सिलो

जवाबों:


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

6
महान! लेकिन मुझे आश्चर्य है कि अगर इसे स्थायी बनाने का कोई तरीका है :)
kolypto

9
महान टिप! सुझाव: >&2पहले सही जोड़कर ; done), वास्तव में stderr के लिए इरादा उत्पादन stderr को लिखा है। यदि आप प्रोग्राम के सामान्य आउटपुट को कैप्चर करना चाहते हैं तो यह मददगार है।
henko

8
निम्नलिखित का उपयोग करता है tput, और मेरी राय में थोड़ा अधिक पठनीय है:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
स्टीफन Lasiewski

2
मुझे लगता है कि प्रत्येक आउटपुट लाइन के लिए 2 tput प्रक्रियाओं को निष्पादित करना सुरुचिपूर्ण नहीं है। हो सकता है कि यदि आप tput कमांड के आउटपुट को एक चर में स्टोर करेंगे और प्रत्येक इको के लिए उपयोग करेंगे। लेकिन फिर, पठनीयता वास्तव में बेहतर नहीं है।
बाल्ज़ पॉसोर

1
यह समाधान व्हॉट्सएप को संरक्षित नहीं करता है लेकिन मुझे इसकी संक्षिप्तता के लिए पसंद है। IFS= read -r lineमदद करनी चाहिए, लेकिन नहीं। यकीन नहीं है कि क्यों।
मैक्स मर्फी

89

विधि 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एक नए अस्थायी फ़ाइल डिस्क्रिप्टर में रीडायरेक्ट करता है 3। बाद 3में वापस चला जाता है stdout
  • sed ...- इसके बाद के संस्करण रीडायरेक्ट की वजह से, sedकी stdinहै stderrनिष्पादित आदेश की। इसका कार्य रंग कोड के साथ प्रत्येक पंक्ति को घेरना है।
  • $'...' एक बैश कंस्ट्रक्शन जिसके कारण बैकस्लैश-एस्कैप्ड कैरेक्टर्स को समझना पड़ता है
  • .* - पूरी लाइन से मेल खाता है।
  • \e[31m - एएनएसआई से बचने का क्रम जो निम्न वर्णों को लाल बनाता है
  • &- sedप्रतिस्थापित चरित्र जो पूरे मिलान स्ट्रिंग (इस मामले में पूरी लाइन) तक फैलता है।
  • \e[m - एएनएसआई भागने का क्रम जो रंग को रीसेट करता है।
  • >&2- आशुलिपि के लिए 1>&2, यह पुनर्निर्देशन sedके stdoutलिए है stderr
  • 3>&1- अस्थाई फाइल डिस्क्रिप्टर को 3वापस रीडायरेक्ट करता है stdout

9
+1 उत्तम उत्तर! पूरी तरह से कम!
मुहूर्त

3
महान उत्तर और इससे भी बेहतर स्पष्टीकरण
डैनियल सेरोडियो

आपको सभी अतिरिक्त पुनर्निर्देशन करने की आवश्यकता क्यों है? ओवरकिल जैसा लगता है
qodeninja

1
क्या इसमें काम करने का कोई तरीका है zsh?
ईयाल लेविन

1
ZSH शॉर्टहैंड पुनर्निर्देशन रूपों को नहीं पहचानता है। यह सिर्फ दो और 1 की जरूरत है, यानी:zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Rekin

26

आप stderred की जाँच भी कर सकते हैं: https://github.com/sickill/stderred


वाह, यह उपयोगिता महान है, केवल एक चीज की आवश्यकता होगी जो एक उपयुक्त भंडार है जो सभी उपयोगकर्ताओं के लिए इसे स्थापित करता है, एक पंक्ति के साथ, इसे सक्षम करने के लिए अधिक काम करने के लिए नहीं।

जब मैंने इसे एक अलग टर्मिनल में एक स्क्रिप्ट के साथ परीक्षण किया, तो अच्छी तरह से काम किया, लेकिन मैं इसे विश्व स्तर पर उपयोग करने में संकोच कर रहा हूं .bashrc। हालांकि धन्यवाद!
जोएल पुर्रा

2
OS X El Capitan में, यह जिस तरह से काम करता है (DYLD_INSERT_LIBRARIES) सिस्टम बायनेरिज़ में "टूटा हुआ" है क्योंकि वे SIP द्वारा संरक्षित हैं। इसलिए अन्य उत्तरों में दिए गए बैश विकल्पों का उपयोग करना बेहतर हो सकता है।
हमीजेल

1
@ Macijail for MacOS कृपया github.com/sickill/stderred/issues/60 का अनुसरण करें ताकि हम एक वर्कअराउंड ढूंढ सकें, एक आंशिक पहले से मौजूद है लेकिन थोड़ा सा छोटी गाड़ी है।
सोरिन

15

Stderr को स्थायी रूप से लाल बनाने का bash तरीका 'exec' को redirect धाराओं का उपयोग कर रहा है। अपने 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;'

मैंने पहले इस पर पोस्ट किया है: STDOUT और STDERR के लिए फ़ॉन्ट रंग कैसे सेट करें



1
यह अब तक का सबसे अच्छा जवाब है; आसान स्थापना के बिना लागू करने के लिए / sudo विशेषाधिकार की आवश्यकता होती है, और सभी आदेशों के लिए सामान्यीकृत किया जा सकता है।
ल्यूक डेविस

1
दुर्भाग्य से यह कमांड चेनिंग (कमांड एंड नेक्स्टकम) के साथ अच्छा नहीं खेलता है। त्रुटि आउटपुट के बाद चला जाता हैहैंडलरक्लेमैंड आउटपुट।
carlin.scott

1
इसी तरह, अगर मैं इसके source ~/.bashrcसाथ दो बार, मेरा टर्मिनल मूल रूप से बंद हो जाता है।
डॉल्फ

@ डॉल्फ: मेरे बशके में मैं इस कोड को फिर से लोड होने से रोकने के लिए आसपास के साथ आसानी से पहरा देता हूं। अन्यथा, समस्या पुनर्निर्देशन 'निष्पादित 9> और 2' के बाद है पुनर्निर्देशन पहले ही हो चुका है। शायद इसे एक स्थिरांक में बदल दें यदि आप जानते हैं कि कहां> 2 मूल रूप से इंगित कर रहा है।
गॉस्प्स


7

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

    #! / Bin / bash

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

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

    # एक्सक्यूट कमांड
    "$ @" 2>> (लाइन पढ़ते समय; गूंज-ई "\ _ [01; 31 मीटर $ लाइन \ e [0 मी"; टी - $ $ TMP_ERRS;
    EXIT_CODE = $?

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

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


2
इसे और अधिक कुशल बनाया जा सकता है अगर "| टी ..." को "किया" के बाद रखा जाए।
जूलियानो

3

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


 #!/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

मैं append> और 2 stderr करने के लिए मुद्रित करने के लिए


4
समस्या का समाधान नहीं। आपने stderr को stdout से अलग करने का एक तरीका प्रदान नहीं किया है, जो कि ओपी में रुचि रखता है।
जेरेमी विज़सर

1

मेरे पास 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

इस समाधान ने मेरे लिए काम किया: 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

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


आप अनुप्रेषित निकास कोड के लिए set -o pipefail;पहले जोड़ सकते हैं(eval
kvaps

"तर्कों में रिक्त स्थान को संरक्षित करने के लिए eval को भी जोड़ते हैं
kvaps


0

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