-1

I'm writing a perl program that captures the output of another program, and I noticed that in a while <FILEHANDLE> loop (so $_ contains the line read), the following occurs:

open XIN, "-|", "test_xsr"; # not getting in real time! FIX
while (<XIN>) {
    print ".";
}

prints

....

after the program finishes while

open XIN, "-|", "test_xsr"; # not getting in real time! FIX
while (<XIN>) {
    print $_;
}

prints

1
2
3
done

in real time while the program runs. (While I'm testing, the program always produces that output.)

Why does this inconsistency occur?
Is it possible to process output in real time without printing$_?

Nonny Moose
  • 121
  • 1
  • 7
  • I'm sure there's got to be a canonical answer that says that, but I can't find it. – Sobrique Jun 14 '17 at 16:45
  • It is not about line-buffering the *input* filehandle. It's about the fact that lines you read from `XIN` have newlines at the end. *Shocking*, I know. So, when you print them, the output gets flushed. Whereas, if you just print dots, the output sits in the buffer until it's filled. – Sinan Ünür Jun 14 '17 at 17:45
  • @SinanÜnür Thanks, you found the solution to my problem. – Nonny Moose Jun 15 '17 at 14:33

1 Answers1

4

By default, if STDOUT is connected to a terminal, STDOUT is only flushed when a newline is encountered or when the buffer is full. There's a newline causing the buffer to be flushed in your second snippet, but not in your first snippet.

Add the following after the print to force the output to be flushed:

STDOUT->flush();

Add the following to your program to always flush after writing to STDOUT:

STDOUT->autoflush();

(Older versions of Perl require use IO::Handle qw( ); to use these.)

ikegami
  • 367,544
  • 15
  • 269
  • 518