שאלה bash: הדפס stderr בצבע אדום


האם יש דרך לעשות להציג bash סטדר הודעות בצבע אדום?


99
2017-08-26 21:10




אני מניח שבאש לעולם לא colorize הפלט שלה: תוכנית כלשהי עשויה לרצות לנתח משהו, ו colorizing יקלקל נתונים עם sequences נמלט. יישום GUI צריך להתמודד עם צבעים, אני מניח. - kolypto
שילוב של Balazz Pozsar ו killdash9 התשובה נותן את חדות: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }  יצירות עבור bash ו- zsh. אין אפשרות להוסיף זאת כתשובה לשאלה b / c. - 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 למעשה נכתב stdr. זה מועיל אם אתה רוצה ללכוד את הפלט הרגיל של התוכנית. - 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: יצירת פונקציה בתסריט bash:

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

השתמש בו כך:

$ color command

שתי השיטות יציגו את הפקודה stderr באדום.

המשך לקרוא הסבר על אופן הפעולה של שיטה 2. יש כמה תכונות מעניינות שהוכיחו על ידי פקודה זו.

  • color()... - יוצר פונקציה bash בשם צבע.
  • set -o pipefail - זוהי אפשרות פגז ששומרת את קוד השגיאה של הפקודה של פקודה שהפלט שלה מוזרק לפקודה אחרת. זה נעשה בתוך subhell, אשר נוצר על ידי סוגריים, כדי לא לשנות את האפשרות pipefail בקליפה החיצונית.
  • "$@" - מבצע את הארגומנטים לפונקציה כפקודה חדשה. "$@" שווה ל "$1" "$2" ...
  • 2>&1 - מפנה מחדש את stderr של הפקודה stdout כך שהוא הופך להיות sed's stdin.
  • >&3 - קצרנות עבור 1>&3, זה מפנה מחדש stdout לתיאור קובץ זמני חדש 3. 3 מקבל ניתוב בחזרה stdout יותר מאוחר.
  • sed ... - בשל הפניות לעיל, sed's stdin האם ה stderr של הפקודה להורג. הפונקציה שלה היא להקיף כל שורה עם קודי צבע.
  • $'...' מבנה bash שגורם לו להבין תווים בריחה נטוש
  • .* - מתאים את כל השורה.
  • \e[31m - רצף הבריחה של ANSI שגורם לתווים הבאים להיות אדומים
  • & - ה sed להחליף תו שמתרחב לכל המחרוזת המתאימה (כל השורה במקרה זה).
  • \e[m - רצף הבריחה של ANSI שמאפס את הצבע.
  • >&2 - קצרנות עבור 1>&2, זה מפנה מחדש sed's stdout ל stderr.
  • 3>&1 - מפנה מחדש את מתאר הקובץ הזמני 3 בחזרה ל stdout.

74
2018-04-23 20:53



+1 התשובה הטובה ביותר! מוחלש מוחלט! - muhqu
תשובה מצוינת ואפילו הסבר טוב יותר - Daniel Serodio
למה אתה צריך לעשות את כל ניתוב מחדש? נראה כמו overkill - qodeninja
@qodeninja ההסבר נותן את המטרה עבור ניתוב מחדש. אם אתה יכול למצוא דרך פשוטה יותר לעשות את זה, אני אשמח לראות את זה! - killdash9
האם יש דרך לגרום לזה לעבוד zsh? - Eyal Levin


אתה יכול גם לבדוק את stredred: https://github.com/sickill/stderred


23
2017-12-13 21:40



וואו, כלי זה הוא נהדר, הדבר היחיד שהוא צריך זה יש מאגר apt כי מתקין את זה עבור כל המשתמשים, עם שורה אחת, לא צריך לעשות יותר עבודה כדי לאפשר את זה. - sorin
נראה כי עבדתי היטב כאשר בדקתי אותו עם סקריפט לבנות במסוף נפרד, אבל אני מהסס להשתמש בו באופן גלובלי (in .bashrc). תודה בכל אופן! - Joel Purra
ב- OS X El Capitan, האופן שבו זה עובד (DYLD_INSERT_LIBRARIES) הוא "שבור" במערכת הקבצים הבינאריים כי הם מוגנים על ידי SIP. אז זה יכול להיות טוב יותר להשתמש באפשרויות באש נתון בתשובות אחרות. - hmijail
@hmijail עבור MacOS אנא פעל github.com/sickill/stderred/issues/60 אז אנחנו יכולים למצוא פתרון, אחד חלקי כבר קיים אבל הוא קצת באגי. - sorin


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


14
2017-08-26 21:18





את הדרך של bash לעשות סטדר אדום לצמיתות משתמש '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;'

פרסמתי על זה בעבר: כיצד להגדיר צבע גופן עבור STDOUT ו- STDERR


11
2018-01-29 08:49



קשור unix.stackexchange.com/questions/367636/... - Blauhirn
זוהי התשובה הטובה ביותר עד כה; קל ליישם ללא התקנה / הדורש זכות sudo, והוא יכול להיות generalised לכל הפקודות. - Luke Davis
למרבה הצער זה לא משחק טוב עם שרשור הפקודה (הפקודה && nextCommand || errorHandlerCommand). פלט השגיאה הולך אחרי הפלט errorHandlerCommand. - carlin.scott
באופן דומה, אם אני source ~/.bashrc פעמיים עם זה, המסוף שלי בעצם נעולה. - Dolph
@ Dolf: ב bashrc שלי אני נשמר בקלות נגד זה עם ההצהרה אם מקיפה כדי למנוע קוד זה מחדש. אחרת, הבעיה היא ניתוב מחדש 'exec 9> & 2' לאחר ניתוב מחדש. אולי לשנות את זה קבוע אם אתה יודע איפה 2> מצביע במקור. - gospes


עשיתי סקריפט עטיפה מיישם את התשובה של Balazz Pozsár ב bash טהור. שמור אותו ב $ שלך PATH ופקודות כדי לצבוע את הפלט שלהם.


    #! / bin / bash

    אם [$ 1 == "--help"]; לאחר מכן
        הד "מבצע פקודה וצובע את כל השגיאות שהתרחשו"
        הד "דוגמה:` basename $ {0} `wget ..."
        הד "(c) o_O Tync, ICQ # 1227-700, תהנה!"
        יציאה 0
        Fi

    # קובץ זמני כדי לתפוס את כל השגיאות
    TMP_ERRS = $ (mktemp)

    # ביצוע פקודה
    "$ $ @> $ 31 $ line \ e [0m" | tee - app $ $ TMP_ERRS]
    EXIT_CODE = $?

    # הצג שוב את כל השגיאות
    אם [-s] $ TMP_ERRS "]; לאחר מכן
        הד \ "\ n \ n \ n \ e [01, 31m === שגיאות === \ e [0m"
        חתול $ TMP_ERRS
        Fi
    rm -f $ 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 מ stdout, וזה מה O.P מתעניין. - Jeremy Visser


יש לי גרסה שונה מעט של התסריט O_o Tync. אני צריך לעשות את המודולים עבור OS X Lion וזה לא מושלם כי התסריט לפעמים משלים לפני הפקודה עטוף. הוספתי לישון אבל אני בטוח שיש דרך טובה יותר.

#!/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/immediate-tell-which-output-was-sent-to-stderr

שמתי את הפונקציה הזאת שלי .bashrc או .zshrcYou

# 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





גרסה באמצעות חמישה

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