bash 命令在 stderr 上 grep 某些内容并将结果保存在文件中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16321415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash command to grep something on stderr and save the result in a file
提问by user2339933
I am running a program called stm. I want to save only those stderr messages that contain the text "ERROR" in a text file. I also want the messages on the console.
我正在运行一个名为 stm 的程序。我只想在文本文件中保存那些包含文本“ERROR”的 stderr 消息。我还想要控制台上的消息。
How do I do that in bash?
我如何在 bash 中做到这一点?
回答by nosid
Use the following pipeline if only messages containing ERRORshould be displayed on the console (stderr):
如果只ERROR应在控制台 (stderr) 上显示包含的消息,请使用以下管道:
stm |& grep ERROR | tee -a /path/to/logfile
Use the following command if all messages should be displayed on the console (stderr):
如果所有消息都应显示在控制台 (stderr) 上,请使用以下命令:
stm |& tee /dev/stderr | grep ERROR >> /path/to/logfile
Edit:Versions without connecting standard output and standard error:
编辑:没有连接标准输出和标准错误的版本:
stm 2> >( grep --line-buffered ERROR | tee -a /path/to/logfile >&2 )
stm 2> >( tee /dev/stderr | grep --line-buffered ERROR >> /path/to/logfile )
回答by Alan Porter
This looks like a duplicate of How to pipe stderr, and not stdout?
这看起来像是How to pipe stderr 而不是 stdout的副本?
Redirect stderr to "&1", which means "the same place where stdout is going". Then redirect stdout to /dev/null. Then use a normal pipe.
将 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'
$
To copy the output from the above command to a file, you can use a > redirection or "tee". The tee command will print one copy of the output to the console and second copy to the file.
要将上述命令的输出复制到文件中,您可以使用 > 重定向或“tee”。tee 命令将输出的一份副本打印到控制台,并将第二份副本打印到文件。
$ stm 2>&1 >/dev/null | grep ERROR > errors.txt
or
或者
$ stm 2>&1 >/dev/null | grep ERROR | tee errors.txt
回答by Markku K.
Are you saying that you want both stderr and stdout to appear in the console, but only stderr (not stdout) that contains "ERROR" to be logged to a file? It is that last condition that makes it difficult to find an elegant solution. If that is what you are looking for, here is my very uglysolution:
您是说您希望 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
I warned you about it being ugly. You could hide it in a function, use mktemp to create the temporary filenames, etc. If you don't want to wait for stm to exit before logging the ERROR text to a file, you could add tail -f stm.err | grep ERROR > error.log &after the other tail commands, and remove the grep command from the last line.
我警告过你它很丑。您可以将其隐藏在函数中,使用 mktemp 创建临时文件名等。如果您不想在将 ERROR 文本记录到文件之前等待 stm 退出,您可以tail -f stm.err | grep ERROR > error.log &在其他 tail 命令之后添加,并删除最后一行的 grep 命令。

