How can I catch a command exit code for later, in a Makefile?

I have a makefile, with a test suite target, like so:


This shows the output from the foo command on stdout, and returns an exit code from foo which is handled by make as normal.

I want to add something to this target, to parse foo‘s output without affecting the existing behaviour – that is:

  1. foo‘s stdout/stderr should be displayed on stdout/stderr, as before
  2. the final outcome of the rcheck target, as far as Make is concerned, is whatever foo‘s exit code was
  3. stdout from foo should be passed to a second command, bar, somehow. bar‘s exit code doesn’t matter, and bar should not output anything to stdout or stderr in addition to 1. above (unless the solution means bar handles 1. itself)

What is the neatest solution here?

Asked By: directhex


If you’re not worried about the timing of data passing from foo to bar, and you’re okay with a tempfile which will need to be handled in your clean target, then simply:

        foo | tee sometempfile
        -bar < sometempfile >/dev/null 2>/dev/null

If on the other hand you care a lot about timing then you could make bar repeat its input to stdout and try something like:

        -(foo; echo $$? > sometempfile) | bar
        exit $(cat sometempfile)

I’m sure there’ll be cleaner ways, but the above came to mind. (Note, both are untested)

Answered By: Daniel Silverstone

If you’re using a shell that supports the pipefail option (bash, ksh, and zsh do), you could do it this way:

    set -o pipefail; foo | tee /dev/stderr | { bar >/dev/null 2>&1; true; }

My ksh manpage documents that option as:

      A pipeline will not complete until all components of the pipeline have
      completed, and the return value will be the value of the last non-zero
      command to fail or zero if no command has failed.

As opposed to the default behavior:

The exit status of a pipeline is the exit status of the last command
unless the pipefail option is enabled.
Answered By: godlygeek
Categories: Answers Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.