Stdout To File1, Stderr To File2, Both Correctly Interleaved To Stdout And File
Given a third-party program, how would one simultaneously:
- write stdout to z.stdout
- write stderr to z.stderr
- pass exit codes appropriately
- write both in correct interleaved order to stdout
Here's the test program (delayed_interleaved_stdout_stderr.pl) I've been using:
#!/usr/bin/env perl
use strict;
use warnings;
# fixme: debug, uncomment to force stdout flushing
# use English '-no_match_vars';
# $OUTPUT_AUTOFLUSH = 1;
# use sleeps to simulate delays and test buffering
use Time::HiRes 'sleep';
foreach my $num ( 0..9 ) {
if ( 0 == $num % 2 ) {
print STDOUT $num, ":stdout\n";
}
else {
print STDERR $num, ":stderr\n";
}
sleep 0.25;
}
So far I've been able to do 1,2,3 with:
( set -o pipefail; \
( set -o pipefail; delayed_interleaved_stdout_stderr.pl \
| tee z.stdout; exit $? \
) 3>&1 1>&2 2>&3 | tee z.stderr; exit $? \
) 3>&1 1>&2 2>&3
Thanks to a related answer by lhunath and a friend, I simplified it to:
delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
However, I haven't been able to get correct interleaved order. stderr prints immediately and the (presumably buffered) stdout all prints at the end.
1:stderr
3:stderr
5:stderr
7:stderr
9:stderr
0:stdout
2:stdout
4:stdout
6:stdout
8:stdout
Running delayed_interleaved_stdout_stderr.pl by itself displays in the proper 0-9 order. Forcing stdout to flush works appropriately (see commented fixme section), but I won't be able to modify the real files.
Maybe I'm missing something basic and I'm beginning to wonder if this is possible at all :(
Answer
I confirmed I can enforce stdout flushing for the third-party programs. In light of this, I'm going with
delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
Thanks for all help!
Related Questions
- → "Box: laravel/homestead-7" producing "sh.exe":box:: command not found"
- → Retrieve user's image selection from website
- → Getting error when using default task in gulp, shows the following error in Gitbash : Task requires a name that is string
- → Homestead Installaton
- → bash: homestead: command not found
- → Troubles with Artisan Tinker encoding
- → How can I access declared variable in bash when executing Laravel Envoy task?
- → coinex exchange API and use Curl /BASH to Place a market order crypto pair
- → Coiex API Curl Could not resolve host
- → How to GREP words, not lines, that contain specific characters, and print entire word
- → Cmd and Git bash have a different result when run a Python code
- → How can I convert ip ranges formatted in ip1-ip2 to cidr format?
- → Pushing to another user's remote repository without the use of pull requests