[Qt-interest] Coordinating stderr between processes in a pipe train
Jeffrey Brendecke
jwbrendecke at icanetix.com
Tue Jul 14 13:42:24 CEST 2009
This is a problem that has been vexing me for a while.
I am developing a library of console applications that process input data in a
series using a traditional filter approach. The following is a text
application I have been using to make sure the plumbling works:
echo xxxx | xq.exe 0 ERROR | xq.exe 0 xx | xq.exe 0 cc | xq.exe 0 dd >NUL:
Here is the code:
#include <QString>
#include <QTextStream>
#include <cstdlib>
int
main( int argc, char** argv )
{
int exitCode( 99 );
QString val;
if ( 3 != argc ) return exitCode;
QTextStream in( stdin );
QTextStream out( stdout );
QTextStream err( stderr );
exitCode = std::atoi( argv[1] );
in >> val;
if ( 0 == exitCode )
{
out << qPrintable(val) << argv[2] << endl;
}
err << argv[2] << " " << exitCode << endl;
return exitCode;
}
I have no problems I can tell with processing stdout. However working with
stderr is proving unreliable as it sometimes gets garbled when put together
on the console.
Given the above commandline, sometimes everything looks OK (the order is not
important for my purposes):
xx 0
cc 0
ERROR 0
dd 0
Other times, it gets garbled (it can get much worse than this):
cxc 0
Ex 0
RROR 0
dd 0
In an outer script, I am capturing stderr and processing from the pipe train
based on the status of the output lines. The test app was made to see why
sometimes lines, for example, begging with "ERROR:" were not being processed.
I have seen the problem both on Linux under bash and on Windows under
cmd.exe.
Note that this relates to set of long-running applications that work together
in such a manner, so capturing all of the stderr from each process in
sequence and then outputing it is not a viable option.
Also note that the underlying reason for analyzing the stderr for errors,
other than making a nice report, is to tell if the pipe train failed. Other
than newer versions of bash (with its $PIPESTATUS[] variable), I have found
no way to do this reliably so that a decision can be made in the next line of
script following the pipe train to proceed or not (pseudocode):
run pipe train
if pipe train succeeds:
do a()
else:
do b()
I need to have this work on Windows (for now) with the option of porting to
Linux later.
Is there something Qt can provide to simplify working with this? This seems
like such a rudimentary problem that basically has been around the 70's.
Thank you for your assistance.
More information about the Qt-interest-old
mailing list