bash:以红色打印stderr

有没有办法使bash以红色显示stderr消息?

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

方法1:使用过程replace:

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

方法2:在bash脚本中创build一个函数:

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

像这样使用它:

 $ color command 

两种方法都会以红色显示命令的stderr

继续阅读方法2如何工作的解释。 这个命令演示了一些有趣的function。

  • color()... – 创build一个名为color的bash函数。
  • set -o pipefail – 这是一个shell选项,用于保留输出到另一个命令中的命令的错误返回码。 这是在由括号创build的子shell中完成的,以便不更改shell中的pipefail选项。
  • "$@" – 执行作为新命令的参数。 "$@"相当于"$1" "$2" ...
  • 2>&1 – 将命令的stderrredirect到stdout以便它成为sedstdin
  • >&31>&3 >&3简写,这将stdoutredirect到一个新的临时文件描述符33后来被路由回stdout
  • sed ... – 由于上面的redirect, sedstdin是被执行的命令的stderr 。 它的function是用颜色代码包围每一行。
  • $'...'一个bash结构,使它理解反斜线转义的字符
  • .* – 匹配整个行。
  • \e[31m – 导致以下字符为红色的ANSI转义序列
  • & – 扩展为整个匹配string的sedreplace字符(本例中为整行)。
  • \e[m – 重置颜色的ANSI转义序列。
  • >&21>&2 >&2缩写,将sedstdoutredirect到stderr
  • 3>&1 – 将临时文件描述符3redirect到stdout

你也可以检查stderred: https : //github.com/sickill/stderred

使stderr永久为红色的bash方式是使用'exec'redirectstream。 将以下内容添加到您的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设置字体颜色

我已经做了一个包装脚本,实现BalázsPozsár的纯粹bash的答案。 将它保存在你的$ PATH和前缀命令中,使它们的输出着色。


     #!/斌/庆典

    如果[$ 1 ==“--help”]; 然后
        回声“执行命令并着色所有发生的错误”
        回声“例如:`basename $ {0}`wget ...”
         echo“(c)o_O Tync,ICQ#1227-700,Enjoy!”
        退出0
        科幻

     #临时文件来捕获所有的错误
     TMP_ERRS = $(mktemp的)

     #执行命令
     “$ @”2>>(while read line; do echo -e“\ e [01; 31m $ line \ e [0m”| tee --append $ TMP_ERRS; done)
     EXIT_CODE = $?

     #再次显示所有错误
    如果[-s“$ TMP_ERRS”]; 然后
         echo -e“\ n \ n \ n \ e [01; 31m ===错误=== \ e [0m”
        猫$ TMP_ERRS
        科幻
     rm -f $ TMP_ERRS

     #完成
    退出$ EXIT_CODE

你可以使用这样的function

 #!/bin/sh 

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

我追加>&2打印到stderr

我有一个稍微修改的O_o Tync脚本版本。 我需要为OS X Lion制作这些mod,这并不完美,因为脚本有时会在包装命令之前完成。 我增加了一个睡眠,但我相信有一个更好的方法。

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

此解决scheme为我工作: 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 

会给我一个红色的输出。

一个使用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