首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在perl中启动bash命令的超时

在perl中启动bash命令的超时
EN

Stack Overflow用户
提问于 2018-04-26 10:16:34
回答 3查看 942关注 0票数 1

我有一个usecase,其中我必须从perl中触发bash命令,并且需要该命令在指定的超时时间内退出,目前我正在使用这个鼠标。

代码语言:javascript
运行
复制
use System::Timeout qw(timeout);
timeout(10, "my bash script")

(由于超时是必要的,所以我不使用system()进行调用)

如果shell脚本退出非零退出代码或命令超时,则此函数返回1。

发行

  1. 此函数仅根据传递的或失败的命令返回1/0(我需要bash脚本的确切退出代码)。
  2. 如果是1,我就不知道脚本是与非零退出代码一起退出的,还是存在超时(区分超时和shell脚本失败)。
  3. 被调用进程的pid是未知的(因此,如果pid由于超时而失败,我需要杀死它)。

满足上述两项条件对我来说很重要(我非常清楚如何在python中实现这一点,但无法获得perl的解决方案)

我不知道在perl中分叉当前进程,然后使用SIGALRM对其进行监视是否会有帮助(Forking将给我分叉进程的pid,而不是我从那个分叉启动的bash脚本。是否会杀死分叉,也会杀死它启动的bash进程?)

谢谢你的帮助

EN

Stack Overflow用户

发布于 2018-04-26 15:11:07

对于运行外部命令时的高级任务,IPC::Run是一个不错的选择。以下内容应涵盖您提到的所有案例。(我承认,对错误消息使用正则表达式并不是最优雅的解决方案,但这里的重点是演示使用该模块的可能性。)

代码语言:javascript
运行
复制
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: $_" }
    };
}

产出(略有修改):

代码语言:javascript
运行
复制
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 ...
票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50040421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档