12

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

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

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

现在的问题是:

  1. 其他输出从何而来?
  2. 如何编写输出只包含过滤行的过滤命令?
4

3 回答 3

12

要回答问题:

  1. 该管道仅将stdoutof连接makestdingrep。make'sstderr仍然连接到终端,因此将在不过滤的情况下打印。
  2. make解决方案是连接stderr到它stdin并忽略stdin

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

这只会打印 grep 的输出,但不会打印 make 或其他工具(如rm.

于 2013-09-20T10:18:17.517 回答
2

我只是想看看我的编译器的警告。使用 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,但我会先查看构建系统和编译器手册页。

于 2016-04-26T15:15:18.243 回答
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

如评论中所见,所有make输出都以 stderr 形式给出,因此第一个解决方案根本不匹配任何内容。因此,我的建议是使用以下内容:

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

然后 grep make_output.log。正如在如何将“tee”与管道一起使用时如何将标准错误写入文件中所见?.

例子

$ 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
于 2013-09-18T13:44:56.200 回答