Perl - can't flush STDOUT or STDERR

Posted by Jim Salter on Programmers See other posts from Programmers or by Jim Salter
Published on 2013-06-24T16:31:11Z Indexed on 2013/06/24 16:36 UTC
Read the original article Hit count: 376

Filed under:

Perl 5.14 from stock Ubuntu Precise repos. Trying to write a simple wrapper to monitor progress on copying from one stream to another:

use IO::Handle;
while ($bufsize = read (SOURCE, $buffer, 1048576)) {
    STDERR->printflush ("Transferred $xferred of $sendsize bytes\n");
    $xferred += $bufsize;
    print TARGET $buffer;
}

This does not perform as expected (writing a line each time the 1M buffer is read). I end up seeing the first line (with a blank value of $xferred), and then the 7th and 8th lines (on an 8MB transfer). Been pounding my brains out on this for hours - I've read the perldocs, I've read the classic "Suffering from Buffering" article, I've tried everything from select and $|++ to IO::Handle to binmode (STDERR, "::unix") to you name it. I've also tried flushing TARGET with each line using IO::Handle (TARGET->flush). No dice.

Has anybody else ever encountered this? I don't have any ideas left. Sleeping one second "fixes" the problem, but obviously I don't want to sleep a second every time I read a buffer just so my progress will output on the screen!

FWIW, the problem is exactly the same whether I'm outputting to STDERR or STDOUT.

© Programmers or respective owner

Related posts about perl