bash命令在stderr上grep某些东西并将结果保存在文件中

时间:2013-05-01 15:41:55

标签: bash shell

我正在运行一个名为stm的程序。我想只保存文本文件中包含文本“ERROR”的那些stderr消息。我也想要控制台上的消息。

我如何在bash中这样做?

3 个答案:

答案 0 :(得分:14)

如果控制台(stderr)上只显示包含ERROR的消息,请使用以下管道:

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 )

答案 1 :(得分:2)

这看起来像是How to pipe stderr, and not stdout?

的副本

将stderr重定向到"& 1",这意味着"与stdout相同的地方"。 然后将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

答案 2 :(得分:0)

您是说您希望stderr和stdout都出现在控制台中,但只有stderr(不是stdout)包含要记录到文件的“ERROR”?这是最后的条件,使得很难找到一个优雅的解决方案。如果您正在寻找,那么这是我的非常丑陋的解决方案:

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创建临时文件名等。如果您不想在将ERROR文本记录到文件之前等待stm退出,则可以在另一个之后添加tail -f stm.err | grep ERROR > error.log & tail命令,并从最后一行删除grep命令。