开发者

What's wrong with this usage of IPC::Open3?

开发者 https://www.devze.com 2023-04-05 20:07 出处:网络
use IPC::Open3; local(*A, *B, *C); my $cmd = \\&run; my @args = (); my $childpid = open3(*A, *B, *C, $cmd, @args);
use IPC::Open3;

local(*A, *B, *C);

my $cmd = \&run;
my @args = ();
my $childpid = open3(*A, *B, *C, $cmd, @args);
print A "stuff\n";
close(A); 
my @outlines = <B>; 
my @errlines = <C>; 
print "STDOUT:\n"开发者_JS百科, @outlines, "\n";
print "STDERR:\n", @errlines, "\n";
close B;
close C;
waitpid($childpid, 0);
if ($?) {
    print "That child exited with wait status of $?\n";
}

sub run {

}

It's reporting:

STDERR:
sh: -c: line 0: syntax error near unexpected token `0x67bc50'
sh: -c: line 0: `CODE(0x67bc50)'

Why?


Looks like $cmd should be an actual shell command, not a perl subroutine. The error message comes from perl trying to execute the stringified reference to the sub, CODE(0x67bc50) in the shell.

To get the return value from the subroutine as the command, use $cmd->(). That might not do what I think you expect it to, though.


You could move the sub into its own script. Or you could use the special "-" command to fork without running exec.

my $pid = open3(*A, *B, *C, '-');
if (!$pid) {
   run();
   exit(0);
}

By the way,

my @outlines = <B>; 
my @errlines = <C>; 

suffers from a race condition. I the child prints enough to STDERR to fill up the pipe, the two processes will deadlock. It's very hard to get this right, so I suggest you use a higher-level module such as IPC::Run.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号