使用IPC :: Open3有什么问题?

时间:2011-09-20 01:55:21

标签: perl

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 {

}

报道:

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

为什么?

2 个答案:

答案 0 :(得分:3)

看起来$cmd应该是一个真正的shell命令,而不是perl子例程。错误消息来自perl,试图对shell中的子CODE(0x67bc50)执行字符串化引用。

要从子例程获取返回值作为命令,请使用$cmd->()。但是,这可能不会达到我的预期。

答案 1 :(得分:1)

您可以将子移动到自己的脚本中。或者您可以使用特殊的“-”命令进行分叉而不运行exec

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

顺便说一下,

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

患有竞争条件。我的孩子打印到STDERR足以填满管道,这两个过程将陷入僵局。这很难做到,所以我建议你使用更高级别的模块,比如IPC :: Run。