【发布时间】:2013-05-01 15:41:54
【问题描述】:
我正在运行一个名为 stm 的程序。我只想在文本文件中保存那些包含文本“错误”的标准错误消息。我也想要控制台上的消息。
如何在 bash 中做到这一点?
【问题讨论】:
我正在运行一个名为 stm 的程序。我只想在文本文件中保存那些包含文本“错误”的标准错误消息。我也想要控制台上的消息。
如何在 bash 中做到这一点?
【问题讨论】:
如果只有包含 ERROR 的消息应显示在控制台 (stderr) 上,请使用以下管道:
stm |& grep ERROR | tee -a /path/to/logfile
如果所有消息都应显示在控制台(stderr)上,请使用以下命令:
stm |& tee /dev/stderr | grep ERROR >> /path/to/logfile
编辑:没有连接标准输出和标准错误的版本:
stm 2> >( grep --line-buffered ERROR | tee -a /path/to/logfile >&2 )
stm 2> >( tee /dev/stderr | grep --line-buffered ERROR >> /path/to/logfile )
【讨论】:
|& 将标准输出和标准错误都连接到管道的 RHS。
这看起来像是 How to pipe stderr, and not stdout? 的副本
将 stderr 重定向到“&1”,这意味着“stdout 所在的位置”。 然后将标准输出重定向到 /dev/null。然后使用普通管道。
$ date -g
date: invalid option -- 'g'
Try `date --help' for more information.
$
$ (echo invent ; date -g)
invent (stdout)
date: invalid option -- 'g' (stderr)
Try `date --help' for more information. (stderr)
$
$ (echo invent ; date -g) 2>&1 >/dev/null | grep inv
date: invalid option -- 'g'
$
要将上述命令的输出复制到文件中,您可以使用 > 重定向或“tee”。 tee 命令将输出的一个副本打印到控制台,第二个副本打印到文件。
$ stm 2>&1 >/dev/null | grep ERROR > errors.txt
或
$ stm 2>&1 >/dev/null | grep ERROR | tee errors.txt
【讨论】:
您是说您希望 stderr 和 stdout 都出现在控制台中,但只有包含“ERROR”的 stderr(不是 stdout)被记录到文件中?正是最后一个条件使得很难找到一个优雅的解决方案。如果那是您正在寻找的,这里是我的非常丑的解决方案:
touch stm.out stm.err
stm 1>stm.out 2>stm.err & tail -f stm.out & tail -f stm.err & \
wait `pgrep stm`; pkill tail; grep ERROR stm.err > error.log; rm stm.err stm.out
我警告过你它很丑。您可以将其隐藏在函数中,使用 mktemp 创建临时文件名等。如果您不想等待 stm 在将 ERROR 文本记录到文件之前退出,您可以在其他 tail 命令之后添加 tail -f stm.err | grep ERROR > error.log & , 并从最后一行删除 grep 命令。
【讨论】: