简体   繁体   中英

Trouble with IPC::Open3

I am writing a simple script using IPC::Open3. The script produces no output to either stdout or stderr, while I would expect output to both.

The complete source code:

#!/usr/bin/env perl 

use strict;
use warnings;
use utf8;

use IPC::Open3;

pipe my $input, my $output or die $!;
my $pid =  open3(\*STDIN, $output, \*STDERR, 'dd', 'if=/usr/include/unistd.h') or die $!;

while(<$input>) {
    print $_."\n";
}
waitpid $pid, 0;

I am fairly certain that I am using IPC::Open3 incorrectly. However, I am still confused as to what I should be doing.

It's the pipe . Without knowing why it's there I can't say more. This works fine.

my $reader;
my $pid =  open3(\*STDIN, $reader, \*STDERR, 'dd', 'if=/usr/include/unistd.h') or die $!;

while(<$reader>) {
    print $_."\n";
}
waitpid $pid, 0;

I realize it's probably just an example, but in case it's not... this is complete overkill for what you're doing. You can accomplish that with backticks.

print `dd if=/usr/include/unistd.h`

IPC::Open3 is a bit overcomplicated. There are better modules such as IPC::Run and IPC::Run3 .

use strict;
use warnings;

use IPC::Run3;

run3(['perl', '-e', 'warn "Warning!"; print "Normal\n";'],
     \*STDIN, \*STDOUT, \*STDERR
);

Your program suffers from the following problems:

  • \\*STDIN (open STDIN as a pipe tied to the child's STDIN ) should be <&STDIN (use the parent's STDIN as the child's STDIN ).
  • \\*STDERR (open STDERR as a pipe tied to the child's STDERR ) should be >&STDERR (use the parent's STDERR as the child's STDERR ).
  • The value you place in $output is being ignored and overwritten. Fortunately, it's being overwritten with a correct value!
  • You use print $_."\\n"; , but $_ is already newline-terminated. Either chomp first, or don't add a newline.
  • open3 isn't a system call, so it doesn't set $! .
  • open3 doesn't return false on error; it throws an exception.

So we get something like:

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw( say );

use IPC::Open3;

my $pid = open3('<&STDIN', my $output, '>&STDERR',
    'dd', 'if=/usr/include/unistd.h');

while (<$output>) {
    chomp;
    say "<$_>";
}

waitpid($pid, 0);

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