#1 楼
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
评论
大!但是我想知道是否有一种方法可以使其永久:)
–kolypto
09年8月26日在21:47
大提示!建议:在;之前添加>&2。完成),则实际上将用于stderr的输出写入stderr。如果要捕获程序的正常输出,这将很有帮助。
– henko
2012年10月31日上午8:12
以下使用tput,在我看来,它更具可读性:命令2>>(在读取行时;执行echo -e“ $(tput setaf 1)$ line $(tput sgr0)”>&2;完成)
– Stefan Lasiewski
13年2月14日在21:59
我认为为每条输出线执行2个输出处理根本不是一件好事。也许您可以将tput命令的输出存储在变量中,并将其用于每个回显。但是话又说回来,可读性并不是真的更好。
– BalazsPozsár
2014年10月7日12:09
此解决方案不保留空格,但为简洁起见,我喜欢它。 IFS =读-r行应该有帮助,但没有帮助。不知道为什么。
–马克斯·墨菲(Max Murphy)
16年7月1日在11:05
#2 楼
方法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()...
—创建一个名为color的bash函数。set -o pipefail
—这是一个shell选项保留命令的错误返回代码,该命令的输出通过管道传递到另一个命令。这是在由括号创建的子外壳中完成的,以免更改外壳中的pipefail选项。 "$@"
—将函数的参数作为新命令执行。 "$@"
等效于"" "" ...
2>&1
—将命令的stderr
重定向到stdout
,使其成为sed
的stdin
。>&3
— 1>&3
的简写,这会将stdout
重定向到新的临时文件描述符3
。 3
稍后被路由回stdout
。sed ...
—由于上述重定向,sed
的stdin
是已执行命令的stderr
。它的功能是用颜色代码包围每行。$'...'
一个bash构造,使它可以理解反斜杠转义的字符.*
—匹配整行。\e[31m
-导致以下字符变为红色的ANSI转义序列&
-sed
替换字符,扩展为整个匹配的字符串(在这种情况下为整行)。 br /> \e[m
-重置颜色的ANSI转义序列。>&2
-1>&2
的缩写,它将sed
的stdout
重定向到stderr
。3>&1
—将临时文件描述符3
重定向回stdout
。评论
+1个最佳答案!绝对低估了!
– muhqu
2013年9月20日上午11:27
很好的答案,甚至更好的解释
–Daniel Serodio
2014年10月22日19:56
有没有办法使其在zsh中工作?
–艾尔·莱文(Eyal Levin)
16年8月25日在9:14
ZSH无法识别速记重定向表格。它只需要再加上两个1,即:zsh:color()(set -o pipefail;“ $ @” 2>&1 1>&3 | sed $'s。*,\ e [31m&\ e [m,'1 >&2)3>&1
–雷金
18年8月2日在10:12
这不会保留执行顺序。
–乔纳
20-4-11的13:55
#3 楼
您还可以签出stderred:https://github.com/sickill/stderred评论
哇,这个实用程序很棒,它唯一需要做的就是拥有一个apt存储库,只需一行即可为所有用户安装它,而无需做更多的工作来启用它。
–索林
2012年4月3日在14:17
当我在单独的终端中使用构建脚本对其进行测试时,似乎运行良好,但是我犹豫要在全球范围内使用它(在.bashrc中)。不过谢谢!
–乔尔·普拉(Joel Purra)
2012年8月24日15:18
在OS X El Capitan中,此工作方式(DYLD_INSERT_LIBRARIES)在系统二进制文件中被“破坏”,因为它们受到SIP的保护。因此,最好使用其他答案中给出的bash选项。
–hmijail哀悼辞职者
16-4-22在21:41
对于MacOS的@hmijail,请关注github.com/sickill/stderred/issues/60,以便我们可以找到一种解决方法,虽然部分解决方法已经存在,但存在一些问题。
–索林
18年7月16日在7:57
这真的很巧妙。这是我所见的唯一答案,不会扰乱stdout和stderr的顺序(据我所知,所有基于shell的解决方案都可以这样做)。
–唐·哈奇
19/12/25在5:29
#4 楼
使stderr永久变为红色的重击方法是使用“ exec”重定向流。将以下内容添加到您的bashrc中:exec 9>&2
exec 8> >(
while IFS='' read -r line || [ -n "$line" ]; do
echo -e "3[31m${line}3[0m"
done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'
我之前在此上发布过:如何为STDOUT和STDERR设置字体颜色
评论
相关:unix.stackexchange.com/questions/367636/…
– phil294
17年5月29日在3:59
到目前为止,这是最好的答案。易于实现,无需安装/不需要sudo特权,并且可以推广到所有命令。
–戴维斯(Luke Davis)
17年9月26日在2:25
不幸的是,这在命令链接(命令&& nextCommand || errorHandlerCommand)中不能很好地发挥作用。错误输出在errorHandlerCommand输出之后。
–carlin.scott
18年6月18日在23:30
类似地,如果我以此来两次获取〜/ .bashrc,我的终端基本上会锁定。
–多尔夫
'18 Sep 11'在20:11
@Dolf:在我的bashrc中,我很容易用周围的if语句来防止这种情况发生,以防止重新加载此代码。否则,问题是重定向已经执行之后,重定向了'exec 9>&2'。如果您知道> 2最初指向的位置,则可以将其更改为常数。
–目标
'18 -10-1在8:48
#5 楼
http://sourceforge.net/projects/hilite/#6 楼
我制作了一个包装脚本,以纯bash形式实现了BalázsPozsár的答案。将其保存在$ PATH和前缀命令中以使其输出着色。
#!/bin/bash if [ == "--help" ] ; then echo "Executes a command and colorizes all errors occured" echo "Example: `basename q4312078q` wget ..." echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!" exit 0 fi # Temp file to catch all errors TMP_ERRS=$(mktemp) # Execute command "$@" 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" | tee --append $TMP_ERRS; done) EXIT_CODE=$? # Display all errors again if [ -s "$TMP_ERRS" ] ; then echo -e "\n\n\n\e[01;31m === ERRORS === \e[0m" cat $TMP_ERRS fi rm -f $TMP_ERRS # Finish exit $EXIT_CODE
评论
如果将“ | tee ...”放在“完成”之后,可以提高效率。
–朱利亚诺
09年8月27日在1:27
#7 楼
您可以使用类似这样的函数
#!/bin/sh
color() {
printf '3[%sm%s3[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
评论
无法解决问题。您尚未提供将stderr与stdout分开的方法,这是O.P.感兴趣的。
– Jeremy Visser
09年8月27日在1:54
#8 楼
我有一个O_o Tync脚本的稍微修改的版本。我需要为OS X Lion制作这些mod,但这并不完美,因为脚本有时会在包装命令之前完成。我增加了睡眠,但是我敢肯定有更好的方法。#!/bin/bash
if [ == "--help" ] ; then
echo "Executes a command and colorizes all errors occured"
echo "Example: `basename q4312078q` 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
#9 楼
此解决方案为我工作: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$(echo -en \033)[0m/") 3>&1 1>&2 2>&3
}
然后例如:
$ rse cat non_existing_file.txt
会给我红色输出。
评论
您可以添加set -o pipefail;之前(用于重定向退出代码的eval
–kvaps
19年6月27日在14:34
还在eval上添加“以保留参数中的空格
–kvaps
19年6月27日在14:42
#10 楼
使用xargs和printf:command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)
#11 楼
使用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
评论
我猜bash永远不会使输出变色:某些程序可能想解析某些内容,而变色会破坏转义序列的数据。我想一个GUI应用程序应该处理颜色。将BalázsPozsár和killdash9的答案结合在一起即可得出清晰的结果:函数颜色{“ $ @” 2>>(sed $'s .. *,\ e [31m&\ e [m,')}}适用于bash和zsh。无法将此作为答案B / C信誉。
我正在等待修改bash的答案。以下所有解决方案实际上都会修改stderr,甚至可能重新排序stderr。当必须保留stderr的确切字节序列时,stdout会中断事情,例如配管时。
这些解决方案的缺点是它们逐行工作,即它们缓冲输入直到遇到NL。尽管在大多数情况下这可能还可以,但是它会禁用依赖于CR和输出刷新的各种进度条。