Consider the following script:
use IO::File;
$| = 1;
my ($handle, $pid) = myPipe();
if ($pid == 0) {
print "$$";
sleep 5;
exit;
}
print "child: ".<$handle>."\n";
sub myPipe {
my $handle = new IO::File();
my $pid = open($handle, "-|");
return ($handle, $pid);
}
In this case, the “child:” message doesn’t appear for 5 seconds after the process starts. If I remove the sleep call from the forked child, then it prints immediately. Why does the forked child have to exit for the pipe to flush to the parent?
There are two issues. First, the child process is buffering its output; and second, the parent process is using the
<>operator, which blocks until a complete line is available, or until end-of-file.So, one way to get the result you were expecting is to have the child process close its output stream immediately after writing:
Another way is to add a newline to the child process’s output, then flush the stream:
The flush is necessary because pipes are (typically) unbuffered, rather than line-buffered as streams connected to the terminal usually are.
A third alternative is to set the child process’s output stream to autoflush: