有没有办法使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
– 将命令的stderr
redirect到stdout
以便它成为sed
的stdin
。 >&3
– 1>&3
>&3
简写,这将stdout
redirect到一个新的临时文件描述符3
。 3
后来被路由回stdout
。 sed ...
– 由于上面的redirect, sed
的stdin
是被执行的命令的stderr
。 它的function是用颜色代码包围每一行。 $'...'
一个bash结构,使它理解反斜线转义的字符 .*
– 匹配整个行。 \e[31m
– 导致以下字符为红色的ANSI转义序列 &
– 扩展为整个匹配string的sed
replace字符(本例中为整行)。 \e[m
– 重置颜色的ANSI转义序列。 >&2
– 1>&2
>&2
缩写,将sed
的stdout
redirect到stderr
。 3>&1
– 将临时文件描述符3
redirect到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