it-swarm.cn

bash:以红色打印stderr

有没有一种方法可以显示bash 标准差 红色消息?

124
kolypto
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
103
Balázs Pozsár

方法1:使用流程替代:

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

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

_color()(set -o pipefail;"[email protected]" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
_

像这样使用它:

_$ color command
_

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

继续阅读以了解方法2的工作原理。此命令演示了一些有趣的功能。

  • color()... —创建一个名为color的bash函数。
  • _set -o pipefail_ —这是一个Shell选项,用于保留命令的错误返回码,该命令的输出通过管道传递给另一个命令。这是在由括号创建的子外壳中完成的,以免更改外壳程序中的pipefail选项。
  • _"[email protected]"_ —将函数的参数作为新命令执行。 _"[email protected]"_等效于_"$1" "$2" ..._
  • _2>&1_ —将命令的stderr重定向到stdout,使其成为sedstdin
  • _>&3_ — _1>&3_的简写,它将stdout重定向到新的临时文件描述符_3_。 _3_稍后被送回到stdout
  • _sed ..._ —由于上面的重定向,sedstdin是已执行命令的stderr。其功能是用颜色代码包围每行。
  • _$'...'_一种bash构造,使它能够理解反斜杠转义的字符
  • _.*_ —匹配整行。
  • _\e[31m_ —导致以下字符变为红色的ANSI转义序列
  • _&_ — sed替换字符,扩展为整个匹配的字符串(在这种情况下为整行)。
  • _\e[m_ —重设颜色的ANSI转义序列。
  • _>&2_ — _1>&2_的简写,它将_sedstdout重定向到stderr
  • _3>&1_ —将临时文件描述符_3_重定向回stdout
93
killdash9

您还可以签出stderred: https://github.com/sickill/stderred

29
sickill

使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;'

我以前在此发布过: 如何为STDOUT和STDERR设置字体颜色

17
gospes
14
quaie

我编写了一个包装脚本,以纯bash形式实现了BalázsPozsár的答案。将其保存在$ PATH和prefix命令中以使其输出着色。

 
#!/ bin/bash 
 
 if [$ 1 ==“ --help”];然后
 echo“执行命令并为发生的所有错误着色” 
 echo“示例:`basename $ {0}`wget ...” 
 echo“(c)o_O Tync ,ICQ#1227-700,Enjoy!“ 
退出0 
 fi 
 
#临时文件以捕获所有错误
 TMP_ERRS = $(mktemp )
 
#执行命令
“ $ @” 2>>(在读取行时;回显-e“\e [01; 31m $ line\e [0m” | tee --append $ TMP_ERRS;完成)
 EXIT_CODE = $?
 
#如果[-s“ $ TMP_ERRS”]再次显示所有错误
;然后
 echo -e“\n\n\n\e [01; 31m ===错误===\e [0m” 
 cat $ TMP_ERRS 
 fi 
 rm -f $ TMP_ERRS 
 
#完成
退出$ EXIT_CODE 
 
7
kolypto

您可以使用这样的功能


 #!/bin/sh

color() {
      printf '\033[%sm%s\033[m\n' "[email protected]"
      # 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
</ code>

我附加>&2以打印到stderr

3
Ali Mezgani

这个解决方案对我有用: 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 "[email protected]"; 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
Eyal Levin

使用xargs和printf:

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

我有一个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
   "[email protected]" 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
Cliff

使用 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
untore