简体   繁体   中英

Perl anonymous pipe no output

Question

Why is nothing printed when using anonymous pipe, unless I print the actual data from pipe ?


Example

use strict;
use warnings;

my $child_process_id = 0;
my $vmstat_command = 'vmstat 7|';
$child_process_id = open(VMSTAT, $vmstat_command) || die "Error when executing \"$vmstat_command\": $!";


while (<VMSTAT>) {
    print "hi" ;
}
close VMSTAT or die "bad command: $! $?";

Appears to hang


use strict;
use warnings;

my $child_process_id = 0;
my $vmstat_command = 'vmstat 7|';
$child_process_id = open(VMSTAT, $vmstat_command) || die "Error when executing \"$vmstat_command\": $!";


while (<VMSTAT>) {
    print "hi" . $_ ;
#                ^^^ Added this
}
close VMSTAT or die "bad command: $! $?";

Prints

hiprocs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
hi r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
hi 1  0      0 7264836 144200 307076    0    0     0     1    0   14  0  0 100  0  0

etc...


Expected behaviour

Would be to print hi for every line of output of vmstat for the first example.


Versions

perl, v5.10.0
GNU bash, version 3.2.51

Misc

It also appears to hang when using chomp before printing the line (which i thought only removes newlines).

I feel like i'm missing something fundamental to how the pipe is read and processed but could not find a similar question. If there is one then dupe this and I'll have a look at it.


Any further information needed just ask.

Alter

print "hi";

to

print "hi\n";

and it also "works"

the reason it fails is that output is line buffered by default

setting $| will flush the buffer straight away

If set to nonzero, forces a flush right away and after every write or print on the currently selected output channel. Default is 0 (regardless of whether the channel is really buffered by the system or not; "$|" tells you only whether you've asked Perl explicitly to flush after each write). STDOUT will typically be line buffered if output is to the terminal and block buffered otherwise. Setting this variable is useful primarily when you are outputting to a pipe or socket, such as when you are running a Perl program under rsh and want to see the output as it's happening. This has no effect on input buffering. See the getc entry in the perlfunc manpage for that. (Mnemonic: when you want your pipes to be piping hot.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM