Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Parallel::ForkManager and Capture::Tiny together?

Tags:

linux

perl

Below is a simplified example of my problem. Here exec should give an error because xecho doesn't exist.

Question

Is there a way to have Capture::Tiny capture the output from 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";
like image 483
Jasmine Lognnes Avatar asked Dec 11 '25 21:12

Jasmine Lognnes


1 Answers

You cannot use Capture::Tiny to capture output from a child process, but you could use the run_on_finish method from Parallel::ForkManager :

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;

Output:

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 => "",
}
like image 97
Håkon Hægland Avatar answered Dec 14 '25 11:12

Håkon Hægland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!