mebbert has asked for the wisdom of the Perl Monks concerning the following question:

All,

Thank you in advance for your attention. I am new to PerlMonks, but have gleaned many valuable tips over the years. I appreciate the efforts of the monks.

My issue appears to be a misunderstanding in buffering, but I admit I'm not entirely sure. I am writing a perl cgi script that makes a system call to run an external program called MAFFT. MAFFT writes results to STDOUT and progress status to STDERR. I would like to capture STDERR and post the progress to a webpage in real time. Everything is working fine, except in an area where MAFFT is writing the progress in the form:

\r 133/8021

For some reason all of the print statements using \r are collecting and will not actually print even though I have set the buffer to autoflush. I am certain that MAFFT is flushing its buffer appropriately because I can see it update when I run it on the command line. My understanding is that autoflushing STDOUT should force this data to print in real time, like the rest of the print statements from MAFFT.

Here is my code. I appreciate any help/tips.

use Data::Dumper; use IO::Handle STDOUT->autoflush; ...upload file, etc... alignSequences("$upload_dir/$filename","$upload_dir/$filename.out"); sub alignSequences { my $filename = shift; my $fileout = shift; open(MSA,"/usr/local/bin/mafft --auto 2>&1 $filename 1> $fileout | +") or die "MSA failed: $!\n"; # Redirect STDOUT to a file and STDERR + to STDOUT while ( <MSA> ) { print OUTFILE Dumper($_); # When I print to Dumper, everythin +g with a \r is part of the same $VAR print statement } close MSA; }

Here is a sample of the Dumper output:

$VAR1 = "...\r 171 / 8232\r 181 / 8232\r 191 / 8232\r 201 / 8232\r + 211 / 8232\r 221 / 8232\r 231 / 8232\r 241 / 8232\r 251 / 8232\ +r 261 / 8232\r 271 / 8232\r 281 / 8232\r 291 / 8232\r 301 / 8232 +\r 311 / 8232\r 321 / 8232...";

Mark

Replies are listed 'Best First'.
Re: Buffering issue with \r (backslash r)?
by ikegami (Patriarch) on Oct 27, 2009 at 07:20 UTC

    You ask Perl to read a line and you're complaining that it doesn't return before a line is received.

    Perhaps you should change the definition of a line by modifying $/ to "\r".

    Or maybe you want to use sysread instead of <> since sysread returns data as it arrives, even if fewer than the amount requested arrive.

      Ahhh...I always overlook basic principles. So <> reads lines by definition. Thank you very much.

        Out of curiosity, I'd like to know what you thought it did.

        <> is either a shortcut for readline or glob depending on how its used.