我有一个usecase,其中我必须从perl中触发bash命令,并且需要该命令在指定的超时时间内退出,目前我正在使用这个鼠标。
use System::Timeout qw(timeout);
timeout(10, "my bash script")(由于超时是必要的,所以我不使用system()进行调用)
如果shell脚本退出非零退出代码或命令超时,则此函数返回1。
发行
满足上述两项条件对我来说很重要(我非常清楚如何在python中实现这一点,但无法获得perl的解决方案)
我不知道在perl中分叉当前进程,然后使用SIGALRM对其进行监视是否会有帮助(Forking将给我分叉进程的pid,而不是我从那个分叉启动的bash脚本。是否会杀死分叉,也会杀死它启动的bash进程?)
谢谢你的帮助
发布于 2018-04-26 15:11:07
对于运行外部命令时的高级任务,IPC::Run是一个不错的选择。以下内容应涵盖您提到的所有案例。(我承认,对错误消息使用正则表达式并不是最优雅的解决方案,但这里的重点是演示使用该模块的可能性。)
use warnings;
use strict;
use IPC::Run qw/ start timeout /;
use Try::Tiny;
my @commands = (
['perl','-e','sleep 1'], # success
['perl','-e','sleep 10'], # failure due to timeout
['perl','-e','exit 123'], # failure due to nonzero exit code
['perl','-e','kill "INT", $$'], # process exits due to signal
['this_command_doesnt_exist'], # other failure
);
for my $cmd (@commands) {
my $h;
try {
print "\nRunning ",join(' ',@$cmd),"\n";
$h = start $cmd, timeout(2);
$h->finish or die "finish with \$?=$?";
print "Success\n";
}
catch {
if (/timeout/i) {
warn "Timeout Error: $_";
warn "killing child process\n";
defined $h && $h->kill_kill;
}
elsif (/\$\?/) {
warn "Exit Code Error: $_";
# from http://perldoc.perl.org/functions/system.html
if ($? == -1) { print "failed to execute: $!\n" }
elsif ($? & 127)
{ printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without' }
else { printf "child exited with value %d\n", $? >> 8 }
}
else { warn "Other Error: $_" }
};
}产出(略有修改):
Running perl -e sleep 1
Success
Running perl -e sleep 10
Timeout Error: IPC::Run: timeout on timer #2 at ...
killing child process
Running perl -e exit 123
Exit Code Error: finish with $?=31488 at ...
child exited with value 123
Running perl -e kill "INT", $$
Exit Code Error: finish with $?=2 at ...
child died with signal 2, without coredump
Running this_command_doesnt_exist
Other Error: Command 'this_command_doesnt_exist' not found in ... at ...https://stackoverflow.com/questions/50040421
复制相似问题