2

パイプで OPEN を使用して実行しているコマンドがあり、タイムアウトを 10 秒に設定し、実行時間がこれを超えるとサブプロセスを中止したいと考えています。しかし、コードが原因でプログラムがハングするだけです。ALARM が正しく配信されないのはなぜですか?

my $pid = 0;
my $cmd = "someCommand";
print "Running Command # $num";
eval {
    local $SIG{ALRM} = sub {                    
        print "alarm \n";
        kill 9, $pid;
    };              
    alarm 10;
    pid = open(my $fh, "$cmd|");
    alarm 0;
};
if($@) {
    die unless $@ eq "alarm \n";
} else {
    print $_ while(<$fh>);
}

編集:

だから以下の答えから、これは私が持っているものです:

my $pid = open(my $fh, qq(perl -e 'alarm 10; exec \@ARGV; die "exec: $!\n" ' $cmd |));
print $_ while(<$fh>);

しかし、これはアラームがタイムアウトしたときにコンソールに ALARM CLOCK を出力します...コードのどこにもこれを指定していません...どうすればこれを取り除くことができますか?また、カスタムアラームイベントハンドラーをどこに配置しますか?

ありがとう!

4

2 に答える 2

3

タイムアウトを 10 秒に設定し、実行時間がこれを超えるとサブプロセスを中止させたい

別のアプローチは、既にお持ちの便利なスクリプト言語を使用して、サブプロセス自体にアラームを設定することです。

my $cmd = "someCommand";
my $pid = open(my $child_stdout, '-|',
   'perl', '-e', 'alarm 10; exec @ARGV; die "exec: $!"', $cmd);
...

子プロセスは最初は perl (まあ、シェル、次に perl) で、それ自体にアラームを設定し、次に exec (replace their own with) になり$someCommandます。ただし、保留中のアラームはs間で継承されexec()ます。

于 2013-08-19T17:21:28.123 に答える
2

コードが行っているのは、open外部プログラム全体ではなく、呼び出しに 10 秒のタイムアウトを設定することだけです。外部コマンドとの残りのやり取りをevalブロックに取り込みたいとします。

eval {
    local $SIG{ALRM} = sub {                    
        print "alarm \n";
        kill 9, $pid;
    };              
    alarm 10;
    $pid = open(my $fh, "$cmd|");
    print while <$fh>;
    close $fh;
    alarm 0;
};
if($@) {
    die unless $@ eq "alarm \n";
}
于 2013-08-19T18:56:40.693 に答える