I am trying to write a simple script that takes standard output and standard err and puts the word STDERR:
at the beginning of each line of standard err. For testing I have a simple script that outputs a couple lines alternating between standard out and standard err:
#!/usr/bin/perl
print "OUT 1\n";
print STDERR "ERR 1\n";
print "OUT 2\n";
print STDERR "ERR 2\n";
When I run it:
lorkenpeist$ ./testscript.pl
OUT 1
ERR 1
OUT 2
ERR 2
And here is my script stderr.awk
to add STDERR:
#!/bin/awk -f
{print "STDERR: " $0}
If I run ./testscript.pl | ./stderr.awk
(which is obviously wrong because I'm piping standard out instead of standard err):
lorkenpeist$ ./testscript.pl | ./stderr.awk
ERR 1
ERR 2
STDERR: OUT 1
STDERR: OUT 2
I see that standard err is output immediately, while standard output is delayed because of the pipe. The original order of the print statements is not preserved.
I can also redirect standard err to standard output:
lorkenpeist$ ./testscript.pl 2>&1 | ./stderr.awk
STDERR: ERR 1
STDERR: ERR 2
STDERR: OUT 1
STDERR: OUT 2
Not only is everything processed by stderr.awk
instead of just standard err, but again the order of the print statements is not preserved. Is there any way to send just the standard err to stderr.awk
, and also preserve the order of the print statements? What I'd really like to see is:
OUT 1
STDERR: ERR 1
OUT 2
STDERR: ERR 2
I'm beginning to suspect that IO redirection simply isn't the answer, but I'm at a loss for alternatives.
EDIT: Given that standard output is buffered and standard err is not, It looks like I don't have complete control over the order in which the print statements appear on the terminal. That being said, I would prefer if order was at least somewhat preserved, instead of all of standard err being printed before any of standard output. Alternatively, is there a way to make standard output and/or pipes unbuffered?