我目前有一个Perl脚本,它在系统上运行外部命令,收集输出,并根据返回的内容执行一些操作。现在,这是我如何运行它(其中$ cmd是一个带有命令设置的字符串):
@output = `$cmd`;
我想改变它,所以如果命令挂起并且在这么多时间之后没有返回值,那么我会终止命令。我将如何异步运行?
答案 0 :(得分:12)
有很多方法可以做到这一点:
答案 1 :(得分:8)
如果你真的只需要在给定的系统调用上设置超时,这比异步编程要简单得多。
您需要的是eval()块内的alarm()。
下面是一个示例代码块,它将这些代码块放入您可以放入代码的子例程中。该示例调用sleep,因此输出并不令人兴奋,但会显示您感兴趣的超时功能。 运行它的输出是:
/ bin / sleep 2失败:超时时间 ./time-out第15行。
$ cat time-out
#!/usr/bin/perl
use warnings;
use strict;
my $timeout = 1;
my @cmd = qw(/bin/sleep 2);
my $response = timeout_command($timeout, @cmd);
print "$response\n" if (defined $response);
sub timeout_command {
my $timeout = (shift);
my @command = @_;
undef $@;
my $return = eval {
local($SIG{ALRM}) = sub {die "timeout";};
alarm($timeout);
my $response;
open(CMD, '-|', @command) || die "couldn't run @command: $!\n";
while(<CMD>) {
$response .= $_;
}
close(CMD) || die "Couldn't close execution of @command: $!\n";
$response;
};
alarm(0);
if ($@) {
warn "@cmd failure: $@\n";
}
return $return;
}
答案 2 :(得分:1)
如果您的外部程序未接受任何输入,请在perlipc
联机帮助页中查找以下字词:
这是一个安全的反推或管道打开阅读:
使用示例代码并使用警报进行保护(perlipc
中也对此进行了解释)。