简体   繁体   English

IPC :: Open3的用法有什么问题?

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

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", @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. 看起来$cmd应该是实际的shell命令,而不是perl子例程。 The error message comes from perl trying to execute the stringified reference to the sub, CODE(0x67bc50) in the shell. 该错误消息来自perl,它试图对shell中的子CODE(0x67bc50)执行字符串化的引用。

To get the return value from the subroutine as the command, use $cmd->() . 要从子例程获取返回值作为命令,请使用$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 . 或者,您可以使用特殊的“ - ”命令进行分叉而不运行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. 如果孩子向STDERR打印足够的墨水以填充管道,则这两个过程将死锁。 It's very hard to get this right, so I suggest you use a higher-level module such as IPC::Run. 很难做到这一点,因此我建议您使用更高级别的模块,例如IPC :: Run。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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