Xyand
Xyand

Reputation: 4488

Piping stdout and stderr inside a Makefile rule

I want to pipe the output of a script to a different program. Something I would normally do using these two forms:

 python test.py 2>&1 | pyrg
 python test.py |& pyrg

My problem is that it doesn't work from inside a makefile:

[Makefile]
test:
    python test.py 2>&1 | pyrg [doesn't work]

I wish to avoid writing a script file that does the work.

Edit:

This seems like a pyrg issue:

python test.py 2>&1 | tee test.out // Writes to the file both stderr and stdout
cat test.out | pyrg                // Works fine!
python test.py 2>&1 | pyrg         // pyrg behaves as if it got no input

This is a bad solution for me as I never get to the cat part in case of a test failure (everything is inside a Makefile rule)

Upvotes: 28

Views: 32580

Answers (4)

Flimm
Flimm

Reputation: 150853

The operator |& doesn't work in all shells, but it does work in Bash. So you need to tell Make to use the Bash shell for it to work, like this:

SHELL=bash

test:
    python test.py |& pyreg

Upvotes: 0

user5359531
user5359531

Reputation: 3555

Strangely, I had the same problem, and solved it like this:

check-errors:
    check-for-errors.sh &> errors.txt

I am not really sure why 2>&1 >errors.txt did not work here, but &> did

Upvotes: 3

Lucas
Lucas

Reputation: 2642

I stumbled upon this question with the same problem and wasn't satisfied with the answer. I had a binary TLBN that failed on test case example2.TLBN.

This is what my make file looked at first.

make:
     ./TLBN example2.TLBN > ex2_output.txt

Which failed with the error message I was expecting and halting the make process.

This is my fix:

make:
    -./TLBN example2.TLBN > ex2_output.txt 2>&1

Note the - at the beginning of the line which tells make to ignore any output to stderr.

Hope this helps someone that has a similar problem.

Upvotes: 11

Xyand
Xyand

Reputation: 4488

It doesn't explain why the straightforward approaches don't work, but it does the trick:

[Makefile]
test: 
    python test.py >test.out 2>&1; pyrg <test.out

Upvotes: 5

Related Questions