How can I capture the stdin and stdout of a system command with a Perl script?

In the middle of the Perl script there is a system command that I want to execute. I have a line that contains the data that needs to be passed to stdin (the command only accepts input from stdin), and I need to write the output written to stdout. I looked at various methods for executing system commands in Perl, and openI think you need a function , except that it looks like I can only write stdin or stdout, not both.

At the moment, it seems to me that the best solution is to use open, redirect stdout to a temporary file and read from the file after the command completes. Is there a better solution?

+3
source share
9 answers

I think you want to take a look at IPC :: Open2

+1
source

IPC :: Open2 / 3 is fine, but I found that I usually really need IPC :: Run3 , which handles simple cases really well with minimal complexity:

use IPC::Run3;    # Exports run3() by default

run3( \@cmd, \$in, \$out, \$err );

The documentation compares IPC :: Run3 with other alternatives. It is worth reading even if you do not decide to use it.

+6
source

IPC:: Open3, , , . STDERR STDOUT.

http://metacpan.org/pod/IPC::Open3

+3

- script,

use IPC::Open2;

, Perl . ( , CPAN.) :

$pid = open2($cmd_out, $cmd_in, 'some cmd and args');

, $cmd_in, , $cmd_out.

stderr , IPC:: Open3.

+3

perlipc , , IPC:: Open2 IPC:: Open3.

+3

, , - IPC::Filter module. :

$output = filter $input, 'somecmd', '--with', 'various=args', '--etc';

, , , . . ( , die s, STDERR , STDERR .)

, , ; , . .

+2

I always do it this way if I expect only one line of output or want to break the result into something other than a new line:

my $result = qx( command args 2>&1 );  
my $rc=$?;  
# $rc >> 8 is the exit code of the called program.

if ($rc != 0 ) {  
    error();  
}  

If you want to deal with multi-line response, get the result as an array:

my @lines = qx( command args 2>&1 );  

foreach ( my $line ) (@lines) {  
    if ( $line =~ /some pattern/ ) {  
        do_something();  
    }  
}  
0
source

If you do not want to include additional packages, you can simply do

open(TMP,">tmpfile");
print TMP  $tmpdata ;
open(RES,"$yourcommand|");
$res = "" ;
while(<RES>){
$res .= $_ ;
}

which is contrary to what you suggested, but should also work.

0
source

Source: https://habr.com/ru/post/1697002/


All Articles