【问题标题】:bash command to grep something on stderr and save the result in a filebash命令在stderr上grep一些东西并将结果保存在一个文件中
【发布时间】:2013-05-01 15:41:54
【问题描述】:

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

如何在 bash 中做到这一点?

【问题讨论】:

    标签: bash shell


    【解决方案1】:

    如果只有包含 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。
    • stm |& grep ERROR 似乎将包含 ERROR 的消息过滤到控制台,但由于某种原因,日志文件的发球似乎总是返回一个空文件,即使我不希望它出现在控制台,stm|& grep ERROR > logfile.txt 不起作用。
    【解决方案2】:

    这看起来像是 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和grepping的问题一样。我只是想将grepped的输出记录到日志文件中。我什至不太关心控制台上的输出.出于某种原因,./stm |& grep ERROR >> log.txt 创建了一个空日志文件,尽管没有重定向到日志文件会在屏幕上提供控制台输出。
    【解决方案3】:

    您是说您希望 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 命令。

    【讨论】:

    • 其实在控制台上显示的要求并不重要。我只是想主要是grep stderr并将其记录到文本文件中。我做./stm |& grep ERROR >> log.txt ,但我没有得到任何文本文件。当我运行 ./stm|& grep ERROR 时,我在控制台上得到过滤后的消息。
    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2014-05-12
    • 2018-08-17
    相关资源
    最近更新 更多