Piping stdout and stderr inside a Makefile rule
Asked Answered
B

4

28

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)

Bye answered 1/8, 2012 at 8:22 Comment(12)
This should work. make passes the entire line to /bin/sh for interpretation, so anything that this shell (which does not need to be your user shell) can understand works.Myrilla
Exactly how does it not work? Try setting export SHELL := /bin/bash somewhere in your makefile.Dextroglucose
The second command runs as if it didn't receive any input from stdin. And it actually runs before the first one. Using || instead of | maintains the order but yet again pyrg doesn't get the input.Bye
@MaximYegorushkin, this setting helped to avoid getting an error when using |&. But it still behaves as in my previous comment.Bye
It shouldn't matter what order the programs are launched. The two will be connected by the pipe even so.Smoothen
@ams, what I mean is that the second program writes its output as if it had nothing in stdin (for pyrg the help text). So it seems they are not connected by the pipe. Only then I see the first program's output on the screen (should have been redirected to the second)Bye
Er, yes, that's quite badly broken then!Smoothen
|& is csh syntax, I wouldn't expect that to work in a makefile. Are you sure there isn't a typo, like putting python test.py 2&>1 | pyrg ? is there now a file 1 in your working directory?Suave
Try it without the 2&>1. Does it pipe stdout?Danell
@evilotto, no typo and no 1 file (unless I intentionally make the typo :) )Bye
If you are fine with a bashism, how about pyrg <(python test.py 2>&1)?Realtor
@MaximEgorushkin has the correct answerSzabo
B
5

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
Bye answered 2/8, 2012 at 6:57 Comment(0)
K
11

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.

Kellsie answered 24/10, 2013 at 5:16 Comment(1)
Your answer is piping to a file, but OP was asking about piping to a processAndrewandrewes
B
5

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
Bye answered 2/8, 2012 at 6:57 Comment(0)
P
3

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

Piled answered 24/3, 2020 at 14:35 Comment(3)
Thanks. > was not working for me, but &> did when I tried it.Gagarin
This pipes to a file, but it doesn't pipe to a process.Andrewandrewes
2>&1 > errors.txt does not work because the redirections are in the wrong order. You want > errors.txt 2>&1. The former leaves fd 2 associated with whatever fd 1 was initially, while the latter associates both fd 2 and fd 1 with errors.txt.Weltanschauung
A
0

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
Andrewandrewes answered 7/6 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.