How to redirect STDOUT,STDERR and keep the message order 
Author Message
 How to redirect STDOUT,STDERR and keep the message order

Hi All,

    I have the following perl code to redirect stdout and stderr to
samefile.

******************************************************************************
#!/usr/local/bin/perl

##Save the original Handles
open tmpSTDOUT, ">&STDOUT";
open tempSTDERR, ">&STDERR";

##Create a new file and redirect STDERR and STDOUT
open STDOUT, ">mylog" or die "Can NOT redirect STDOUT\n";
open STDERR, ">&STDOUT" or die "Can not duplicate STDOUT\n";

select STDERR; $| = 1;
select STDOUT; $| = 1;

exec ("./a.out");

close STDOUT;
close STDERR;

##Restore Originals
open STDOUT, ">&tmpSTDOUT";
open STDERR, ">&tmpSTDERR";
******************************************************************************
a.out is executable from "C" program which does
   for (int i = 0; i<20; i++)
      {
          fprintf(stdout,"MESSAGE TO STDOUT %d\n",i);
          fprintf(stderr,"MESSAGE TO STDERROR %d\n",i);
       }

When run the above program, I am not getting the messages in the order
in which they get printed. I am getting stderr messages first and then
stdout messages.
I want to kkep the order in which the messages are generated. I am
unable to figure out where I am going wrong. PLEASE HELP.

thanks and regards,
Ravi



Fri, 08 Oct 2004 11:48:42 GMT  
 How to redirect STDOUT,STDERR and keep the message order
Hi Ravi,

Are you sure that you want to use "exec" here?  From your code I get the
impression that you expect it to behave like "system()".

Anyway, you may do a redirection like this:

exec('ls -l zzz >OUTPUTFILE 2>&1');

This means to redirect the STDERR to STDOUT and then to redirect both
to output file named OUTPUTFILE.  If you ommit ">OUTPUTFILE", both error
messages and normal output will go to STDOUT.

However, once again, check the difference between "system()" and
"exec()" - maybe "system()" is what you need.

Regards,

- Alex

Quote:

> Hi All,

>     I have the following perl code to redirect stdout and stderr to
> samefile.

 > ...


Fri, 08 Oct 2004 20:28:12 GMT  
 How to redirect STDOUT,STDERR and keep the message order

Quote:

> Hi All,

>     I have the following perl code to redirect stdout and stderr to
> samefile.
> #!/usr/local/bin/perl

> ##Save the original Handles
> open tmpSTDOUT, ">&STDOUT";
> open tempSTDERR, ">&STDERR";

> ##Create a new file and redirect STDERR and STDOUT
> open STDOUT, ">mylog" or die "Can NOT redirect STDOUT\n";
> open STDERR, ">&STDOUT" or die "Can not duplicate STDOUT\n";

> select STDERR; $| = 1;
> select STDOUT; $| = 1;

Setting $| only unbuffers within the perl script.

Quote:
> exec ("./a.out");

exec() replaces the current process with the argument.
The lines after this are never reached.

Quote:
> close STDOUT;
> close STDERR;

> ##Restore Originals
> open STDOUT, ">&tmpSTDOUT";
> open STDERR, ">&tmpSTDERR";

The only reason you don't notice these not being run is that this is
probably you're entire code.

Quote:
> a.out is executable from "C" program which does
>    for (int i = 0; i<20; i++)
>       {
>           fprintf(stdout,"MESSAGE TO STDOUT %d\n",i);
>           fprintf(stderr,"MESSAGE TO STDERROR %d\n",i);
>        }

The c libraries stdio will check if the output stream is a terminal...
if it's a terminal, stdout is line-buffered.  If it's not a terminal,
stdout is block-buffered.  You need to either fflush(stdout) after each
fprintf, or else alter the buffering mode on it before your loop.

Quote:
> When run the above program, I am not getting the messages in the order
> in which they get printed. I am getting stderr messages first and then
> stdout messages.

That's because the stderr messages get printed right away, and the
stdout messages get stored into a buffer, and not printed until either
the buffer fills up, or fflush is called, or the program exits.

Since it's a short script, the buffer doesn't fill up.  And you don't
call fflush.  So, the contents of the buffer are never printed until the
program exits.

Quote:
> I want to kkep the order in which the messages are generated. I am
> unable to figure out where I am going wrong. PLEASE HELP.

The problem is with the C program, not with perl.
Well, there *is* a problem with your perl program [you're using exec
instead of system()], but that's easily fixed...  Of course, a much
better solution than the redirecting you're doing would be:

use IPC::Open3;
use File::Spec;

open( MYLOG, ">+", "mylog" ) or die "Couldn't open mylog: $!";
open( PROG_GETS_NO_INPUT, "<", File::Spec->devnull )
   or die "Couldn't open null input file for a.out's stdin.\n";
waitpid( open3(
   "<&PROG_GETS_NO_INPUT", ">&MYLOG", ">&MYLOG",
   "./a.out"
), 0 ) or die "waitpid failed: $!";

die "./a.out died from signal ".($? & 0xFF)."\n" if $? & 0xFF;
die "./a.out exited with code ".($?  >>  8)."\n" if $? >> 8;

print "./a.out ran and exited ok.\n";
print "Output of a.out was:\n";
seek MYLOG, 0, 0;
print while sysread MYLOG, $_, 8192;
__END__

The two opens, the open3, and the waitpid in my code are about
equivilant to your six opens your system (well, your exec, but you meant
for it to be a system), and your two closes.

The extra stuff I have is, well, extra.  You really should test the
contents of $? somewhere, and obviously you need to *do* something with
your mylog file.

--
print reverse( ",rekcah", " lreP", " rehtona", " tsuJ" )."\n";



Sat, 09 Oct 2004 00:26:26 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Capturing STDOUT and STDERR and preserving order?

2. HELP - with redirect of STDERR and STDOUT

3. redirect STDERR to STDOUT ?????

4. redirecting stderr and stdout

5. writing to terminal even with STDOUT and STDERR redirected

6. assigning STDERR whild redirecting STDOUT to a file

7. Problem with redirecting STDOUT and STDERR

8. Redirect stderr to stdout w/ Perl under Unix?

9. Redirecting STDERR to STDOUT (on NT)

10. HELP - with redirect of STDERR and STDOUT

11. need to redirect STDOUT and STDERR

12. Redirecting stdout/stderr from a call to system()

 

 
Powered by phpBB® Forum Software