【问题标题】:Grepping Make OutputGrepping Make 输出
【发布时间】:2013-09-23 07:27:52
【问题描述】:

当尝试从 make 过滤很长的输出以获取特定的警告或错误消息时,第一个想法是这样的:

$ make | grep -i 'warning: someone set up us the bomb'

但结果并不完全令人满意。输出不仅包含来自grep 的过滤结果,还包含来自make 目标某处使用的其他工具的stdoutstderr 消息。

现在的问题是:

  1. 其他输出来自哪里?
  2. 如何编写过滤命令,输出只包含过滤后的行?

【问题讨论】:

    标签: grep makefile


    【解决方案1】:

    排除标准错误:

    make 2>/dev/null | grep -i 'warning: someone set up us the bomb'
    

    示例

    $ ls
    hello
    $ ls hello bye
    ls: cannot access bye: No such file or directory # <--- this is stderr
    hello
    $ ls hello bye 2>/dev/null # <--- stderr are sent to /dev/null, so don't appear
    hello
    

    正如在 cmets 中看到的,所有make 输出都作为标准错误给出,因此第一个解决方案根本不会匹配任何东西。因此我的建议是使用以下内容:

    make 2> >(tee make_output.log >&2)
    

    然后 grep make_output.log。正如在How do I write stderr to a file while using “tee” with a pipe? 上看到的那样。

    示例

    $ ls aaa
    ls: cannot access aaa: No such file or directory
    $ ls aaa 2> >(tee stderr.log >&2)
    ls: cannot access aaa: No such file or directory
    $ cat stderr.log 
    ls: cannot access aaa: No such file or directory
    

    【讨论】:

    • 如果你先 make | tee myfile 然后 grep myfile 呢?
    • 是的。我看到的是make 输出被视为stderr。当grep 使用标准输入时,您的grep 没有做任何事情。我认为tee 解决方案可以工作,如果你把它做成一个临时文件然后删除。以make | tee myfile; grep text myfile; rm myfile 为例
    • 您最好查看make 手册页,看看是否有任何选项提供更好的输出。正如我之前所说,当前的make 返回的 stderr 必须以不同的方式处理。
    • @erikb85 如果这是您的反对意见,请考虑到反对那些试图帮助您的人并不是让他们想再做一次的最佳方式。万一是别人,最好知道原因,因为我的回答没有错。
    • 我之前试图向您解释它实际上是错误的,因为它不会导致预期的结果。预期的结果只是从 grep 中获取输出。实际结果是根本没有输出。
    【解决方案2】:

    回答问题:

    1. 管道只连接makestdout和grep的stdinmakestderr 仍然连接到终端,因此将不经过滤打印。
    2. 解决方案是将makestderr 连接到其stdin 并忽略stdin

      $ make 2>&1 >/dev/null | grep -i 'warning: someone set up us the bomb'
      

    这只会打印 grep 的输出,而不会打印来自 make 或其他工具(如 rm)的输出。

    【讨论】:

    【解决方案3】:

    我只是想看看我的编译器发出的警告。使用 make 的静音选项让我接近了我想要的位置。

    来自 make 手册页:

    -s, --silent, --quiet                                                                                                                       
    Silent operation; do not print the commands as they are executed.
    

    我仍然想忽略大量编译器警告,所以我在调用 make 时设置了 CFLAGS

    例如:

    make -s CFLAGS="-Wno-deprecated-declarations"
    

    如果你使用 libtool 这也很方便

    make LIBTOOLFLAGS='--silent' --quiet
    

    如果我只对特定文件或一组文件感兴趣,我会使用 touch 命令,然后使用静默 make。

    触摸 foo.c; make -s CFLAGS="-Wno-deprecated-declarations"

    最初我开始尝试 grep make 输出,但静默调用 make、控制编译警告和触摸文件以限制编译会更干净。毕竟你仍然可以使用 grep,但我会先查看构建系统和编译器手册页。

    【讨论】:

    • 你能改写一下吗?我很难看出你的答案和问题之间的相关性。
    • 就我而言,我试图查看执行 make 时打印的编译警告。了解谁打印了您感兴趣的警告以及实际的警告消息是什么会很有用。如果没有这些信息,最初的问题只是询问如何在 BASH Programming - Introduction HOW-TO 中涵盖的 shell 中重定向输出,而且很可能是一个重复的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-04-25
    • 2020-04-30
    • 2018-12-13
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多