erikbstack
erikbstack

Reputation: 13254

Grepping Make Output

When trying to filter very long output from make for specific warnings or error messages, the first idea would be something like this:

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

The result is not fully satisfying, though. The output will not just contain the filter results from grep but also stdout and stderr messages from other tools that are used in the make target somewhere.

The question now is:

  1. Where does the other output come from?
  2. How to write the filter command that the output will only contain the filtered lines?

Upvotes: 12

Views: 9279

Answers (3)

f3xy
f3xy

Reputation: 774

I just wanted to see the warnings from my compiler. Using the silent option of make got me close to where I wanted.

From the make man page:

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

There were still a large number of compiler warnings I wanted to ignore so I set the CFLAGS when I called make

for example:

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

If you are using libtool this also is very hand

make LIBTOOLFLAGS='--silent' --quiet

If I'm only interested in a specific file or set of files I use the touch command followed by a silent make.

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

Originally I set out trying to grep make output, but it's cleaner to call make silently, control your compilation warnings, and touch files to limit the compilation. After all this you could still use grep, but I would look at the build system and compiler manpages first.

Upvotes: 2

erikbstack
erikbstack

Reputation: 13254

To answer the questions:

  1. The pipe only connects the stdout of make to the stdin of grep. make's stderr is still connected to the terminal in will therefore be printed without filtering.
  2. The solution is connect make's stderr to its stdin and ignore the stdin

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

This only prints the output of grep, but nothing from make or other tools like rm.

Upvotes: 14

fedorqui
fedorqui

Reputation: 289775

Exclude the stderr:

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

Example

$ 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

As seen in the comments, all make output is given as stderr, so that the first solution would not match anything at all. Hence my proposal is to use the following:

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

And then grep the make_output.log. As seen on How do I write stderr to a file while using “tee” with a pipe?.

Example

$ 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

Upvotes: 1

Related Questions