Reputation: 215
I have a script running as so:
cat in | prog1 2>log1 | prog2 2>log2 | prog3 2>log3 > out
<in>
can have millions of lines and I want each program to only produce output on STDOUT
when the next program's STDIN
has been consumed.
This is because prog1
uses system resources that prog2
cleans up once it's done with it.
So basically I want cat
to "pause" between line writes until said lines have been consumed by prog1
, and onward down the line.
I have tried using stdbuf
but that doesn't appear to have any effect, i.e.:
stdbuf -o0 cat in | stdbuf -o0 -i0 prog1 2>log1 | stdbuf -o0 -i0 prog2 2>log2 | stdbuf -o0 i0 prog3 2>log3 > out
Using pv -l
between each pipe confirms the speed difference, and also tail -f
of the different log files.
Is there a way to do this?
I am aware that this will adversely affect performance.
PS I also want the whole pipe to exit when any of the programs exit, and each of the programs are legacy written in either perl or python, so they can't just be combined.
Thanks in advance!
Upvotes: 0
Views: 287
Reputation: 2030
Why do you insist on using pipes? The whole point of piping data is "First In, First Out". If you want regimented processes, use temporary files.
prog1 < in 2>log1 > $(mktemp)
prog2 < $_ 2>log2 > $(mktemp)
# etc...
edit: In this context, $_
means "the last argument of the last command line".
Upvotes: 1