7stud has asked for the wisdom of the Perl Monks concerning the following question:
Dear Monks,
Do pipes add a layer of buffering? Here is a simple program:
#!/usr/bin/env perl use strict; use warnings; use 5.010; say 'hello'; say 'I need a rest. Sleeping...'; sleep 10;
When I run that program, I see two lines of output, and then the program hangs while it sleeps.
The docs say this about open():
If the filename begins with '|', the filename is interpreted as a command to which output is to be piped, and if the filename ends with a '|', the filename is interpreted as a command which pipes output to us.
Here is a program that executes the previous program:
open (my $INFILE, '2perl.pl |') or die "couldn't start program: $!"; while (<$INFILE>) { print; } close $INFILE;
In this case, the program hangs immediately, and it's only after the first program finishes sleeping(and executing) that any output is displayed. Therefore, it seems like the pipe is adding buffering to a program that was originally unbuffered.
However, if I add the following line to the first program:
$| = 1;then run the second program, the output from the first program is immediately displayed and then the program hangs. That result makes it seem like the first program buffers by default, and the $|=1 turns off the buffering.
So how do you explain that apparent contradiction? Why do I need to set $| to 1 when the original program didn't seem to buffer when I ran it directly? What if I can't add $|=1 to the first program?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: open() with a pipe
by ikegami (Patriarch) on Nov 30, 2009 at 07:46 UTC | |
by 7stud (Deacon) on Nov 30, 2009 at 15:36 UTC |