読者です 読者をやめる 読者になる 読者になる

Perl 外部コマンド実行中にタイムアウトで終了させたい

ループ回しながら動的に引数作って外部コマンドを実行させつつ、遅いのはタイムアウトさせたい。
こんなかんじ?

#!/usr/bin/env perl
use strict;
use warnings;
use IPC::Open3 qw/open3/;

my $command;
my $timeout = 3;

foreach (0..3) {
    $command = "sleep $_; echo $_";
    print join '', _exec($command);
}

sub _exec {
    my $command = shift;
    my @res;
    my $pid;
    eval{
        local $SIG{ALRM} = sub {
            die "pid:$pid ($command) is timeout\n"
        };
        alarm $timeout;
        my ( $writer, $reader );
        $pid = open3( $writer, $reader, 0, $command );
        close $writer;
        @res = <$reader>;
        waitpid($pid, 0);
        alarm 0;
    };
    if ($@) {
        warn $@;
        kill("TERM", $pid) if $pid;
        return;
    }
    return @res;
}

% perl open3.pl
0
1
2
pid:20662 (sleep 3; echo 3) is timeout

参考
alarm - perldoc.perl.org
IPC::Open3 の正しい使い方 (re .pl な config ファイルのコンパイルがとおるかチェックしてみる - TokuLog 改メ tokuhirom’s blog) - kazuhoのメモ置き場

ハッシュを配列に入れた時になんかおかしくなる!!1

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my @array;

foreach (0..4) {
    push @array, {
        id => $_,
    };
}
foreach (0..10) {
    print '$_ is '.$_."\n";
    print "array size is ".scalar @array."\n";
    last if $_ > scalar @array;
    print $array[$_]->{id}."\n";
}

warn Dumper \@array;

% perl array_test.pl [~/Dropbox/script]
$_ is 0
array size is 5
0
$_ is 1
array size is 5
1
$_ is 2
array size is 5
2
$_ is 3
array size is 5
3
$_ is 4
array size is 5
4
$_ is 5
array size is 5
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$_ is 6
array size is 6
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$_ is 7
array size is 7
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$_ is 8
array size is 8
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$_ is 9
array size is 9
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$_ is 10
array size is 10
Use of uninitialized value in concatenation (.) or string at array_test.pl line 17.

$VAR1 = [
{
'id' => 0
},
{
'id' => 1
},
{
'id' => 2
},
{
'id' => 3
},
{
'id' => 4
},
{},
{},
{},
{},
{},
{}
];

こんなふうにループが終わらない!!!


追記
autovivificationってやつらしいね

Perl - autovivificationとうまく付き合う - Qiita