如何使用Parallel :: ForkManager和Capture :: Tiny?

时间:2014-12-28 16:48:20

标签: linux perl

以下是我的问题的简化示例。此处exec应该会出错,因为xecho不存在。

问题

有没有办法让Capture::Tiny捕获Parallel::ForkManager的输出?

#!/usr/bin/perl
use strict;
use warnings;
use Parallel::ForkManager;
use Capture::Tiny 'capture';

my ($stdout, $stderr, $exit) = capture {
    my $pm = Parallel::ForkManager->new(5);
    my $pid = $pm->start;
    if (!$pid) {
        no warnings;  # no warnings "exec" is not working
        exec("xecho test");
        $pm->finish;
    }
};

print "$stdout\n";
print "$exit\n";
print "$stderr\n";

1 个答案:

答案 0 :(得分:1)

您无法使用Capture::Tiny来捕获子流程的输出,但您可以使用Parallel::ForkManager中的run_on_finish方法:

use strict;
use warnings;

use Capture::Tiny qw(capture);
use Data::Dump;
use Parallel::ForkManager;

my $pm = Parallel::ForkManager->new(5);
$pm -> run_on_finish (
  sub {
    my (
        $pid, $exit_code, $ident, $exit_signal, 
        $core_dump, $data_structure_reference
    ) = @_;

    my $info = ${$data_structure_reference};
    print "Received from child: \n";
    dd $info;
  }
);

my $pid = $pm->start;
if (!$pid) {
    my ($stdout, $stderr, $exit) = capture {
        sleep 4;
        exec("xecho");
    };
    my $info = {stdout => $stdout, stderr => $stderr, exit=> $exit};
    $pm->finish(0, \$info);
}

print "Master: waiting for child..\n";
$pm->wait_all_children;

输出:

Master: waiting for child..
Received from child: 
{
  exit   => 0,
  stderr => "Can't exec \"xecho\": No such file or directory at ./p.pl line 28.\n",
  stdout => "",
}