立即知道哪个输出已发送到stderr


8

自动执行任务时,明智的做法是先手动对其进行测试。但是,如果可以立即识别出发往stderr的任何数据,并且将其与发往stdout的数据区分开来,并且将所有输出放在一起,则这将是有帮助的,这样就可以清楚地知道事件的顺序是什么。

最后一个不错的选择是,如果在程序退出时打印了返回代码。

所有这些事情将有助于自动化。是的,我可以在程序完成时回显返回代码,是的,我可以重定向stdout和stderr;我真正想要的东西是一些shell,脚本或易于使用的重定向程序,该程序以黑色显示stdout,以红色显示stderr与它交错,并在最后打印退出代码。

有野兽吗?[如果有关系,我正在Mac OS X上使用Bash 3.2]。


更新:对不起,距离我看过已有几个月了。我提出了一个简单的测试脚本:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

在我的测试中(可能是由于缓冲的方式),rse和hilite会显示stdout中的所有内容,然后显示stderr中的所有内容。fifo方法使顺序正确,但似乎使stderr线后面的所有内容着色。ind抱怨我的stdin和stderr行,然后将stderr的输出放在最后。

这些解决方案中的大多数都是可行的,因为仅将最后的输出发送到stderr是不典型的,但是,仍然有一些更好的解决方案还是很不错的。


如果像我一样懒惰(或手指酸痛),则可以使用以下解决方案(例如rse zsh)抓取一个subshel​​l,现在所有命令都会为stderr着色。
偏置

Answers:


3

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


不幸的是,对于像OP这样的Mac用户,stderred破坏了“打开”和“ mvim”。
AlcubierreDrive

这样可以很好地工作,并且由于其工作方式而以正确的方式获取输出顺序。设置一次,然后在您的配置文件中将其打开,只要写入stderr,就会收到红色消息。
克林顿·布莱克莫尔

1

9

我只是设计了一种涉及FIFO的疯狂方法。

$ mkfifo foo
$ grep --color . foo &
$ your_command 2>foo

如果您希望stderr输出分开,则可以打开两个单独的shell,并grep --color . foo在其中一个不带的情况下运行“ ” &,然后在另一个中运行命令(仍使用2>foo)。您将在其中grep一个中获得stderr,而在主要中获得stdout。

之所以可行,是因为stderr输出通过FIFO路由到grep --color,其默认颜色为红色(至少对我来说是红色)。完成后,只需rmFIFO(rm foo)。

警告:我真的不确定这将如何处理输出顺序,您必须对其进行测试。



7

是的,这是可能的。参阅此站点上的“使STDERR红色”部分,以获取工作示例。

基本代码是这个

# 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
}

函数本身给出了简要说明。要做的是将STDOUT和STDERR移开,因此sed将STDERR设为1,将其着色,然后将其交换回去。在这里将文件流3视为临时变量。

通话非常简单

rse commands

但是,某些调用将无法按预期方式工作;注意事项均在链接页面上提供。

顺便说一句,我认为也有可能提供以下形式的解决方案

commands | rse 

其中rse将使输出着色。

我也找到了似乎可以做到这一点的hilite项目。我还没有尝试过,但这可能正是您想要的。

hilite是一个微型实用程序,它执行您指定的命令,突出显示打印到stderr的所有内容。它主要设计用于构建,以使警告和错误像老生常谈一样突出。

其他相关项目:


rse和hilite非常接近我想要的。
克林顿·布莱克莫尔

1

另一个程序是ind:

http://://www.habets.pp.se/synscan/programs.php?prog = ind(您必须自己组装超链接,每个答案我没有足够多的分数)。那里有一个截图,甚至是一个截屏。

它可以很方便地运行子流程,而其他人可能不会。这可以影响顺序的重要性(通常如此),因为stderr会立即在终端中刷新,并且当它不是tty时,stdout将被完全缓冲。

有关完整说明,请参见:http : //blog.habets.pp.se/2008/06/Buffering-in-pipes

另外,ind还可以使用交互式程序和控制字符。从“ ind bash -i”开始,Bash的工作原理与正常一样。

这可以在保留Ctrl-P等的同时为您提供颜色。

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i

1

这里有很多突出显示stderr输出的响应。我只能在一行中添加一个相当简单的内容,并将其附加到命令中:

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

但是您每次都必须在命令后添加它。

我个人而言,就像@nagul提到的可能性一样,将rse函数添加到bashrc中。

但是我想添加用于打印退出代码的解决方案。您可以将此值添加到bash提示行的开头:

hostname$ command
  Some error occurred. Returned exit code.
EC hostname$

其中EC是命令的退出代码。

我以这种方式进行设置,当退出代码为0时,将不会打印该退出代码,但是在下次出现红色提示之前,会打印其他任何值。

整个技巧在〜/ .bashrc中完成:

my_prompt() {
 EXITSTATUS="$?"
 RED="\[\033[1;31m\]"
 OFF="\[\033[m\]"

PROMPT="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

默认情况下,提示行由PS1变量定义。将此处的内容复制到变量PROMPT中,然后创建带有或不带有退出代码的PS1变量。

Bash将在提示中的PS1变量中显示信息。


这正是我在寻找的东西,谢谢!
Dylon

1

annotate-output实用程序(devscriptsDebian软件包),如果您想要不加颜色的话

$ annotate-output /tmp/test.py    
14:24:57 I: Started /tmp/test.py
14:24:57 E: this is stderr
14:24:57 O: this is stdout
14:24:57 O: this is stdout again
14:24:57 I: Finished with exitcode 0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.