26

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)

Xyand
  • 4,470
  • 4
  • 36
  • 63
  • 4
    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. – Simon Richter Aug 01 '12 at 08:26
  • 3
    Exactly how does it not work? Try setting `export SHELL := /bin/bash` somewhere in your makefile. – Maxim Egorushkin Aug 01 '12 at 08:34
  • 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. – Xyand Aug 01 '12 at 08:51
  • @MaximYegorushkin, this setting helped to avoid getting an error when using `|&`. But it still behaves as in my previous comment. – Xyand Aug 01 '12 at 09:00
  • 1
    It shouldn't matter what order the programs are launched. The two will be connected by the pipe even so. – ams Aug 01 '12 at 17:10
  • @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) – Xyand Aug 01 '12 at 18:41
  • Er, yes, that's quite badly broken then! – ams Aug 01 '12 at 21:09
  • `|&` 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? – evil otto Aug 01 '12 at 22:29
  • Try it without the 2&>1. Does it pipe stdout? – walrii Aug 02 '12 at 02:51
  • @evilotto, no typo and no `1` file (unless I intentionally make the typo :) ) – Xyand Aug 02 '12 at 06:28
  • If you are fine with a bashism, how about `pyrg <(python test.py 2>&1)`? – tripleee Aug 02 '12 at 07:14
  • @MaximEgorushkin has the correct answer – Manu Jun 16 '16 at 17:25

3 Answers3

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.

Lucas
  • 2,514
  • 4
  • 27
  • 37
4

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
Xyand
  • 4,470
  • 4
  • 36
  • 63
2

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

user5359531
  • 3,217
  • 6
  • 30
  • 55