首页 文章

Perl如何正确处理系统命令(包括超时杀死和捕获RC / STDERR / STDOUT)

提问于
浏览
0

从Perl脚本我想执行各种系统命令并在我的脚本中处理输出 .

该脚本将自动运行,因此我想确保没有命令挂起等 .

我愿意接受任何反馈 .

我对命令执行的要求:

  • 超时 - >如果命令运行时间超过XX秒,则应该终止其进程

  • 如果命令返回信息,则不必等待超时结束

  • 我想在脚本中捕获退出状态,STDERR,STDOUT .

这是我从其他stackoverflow问题中得出的一个例子:Kill a hung child process

目前什么对我不起作用:

  • 无法捕获已执行命令的退出状态

  • 无法捕获已执行命令的STDERR

码:

my $cmd = "sleep 15"; # other tests i use -> "echo bla" and "alkjdsf"
my $TIMEOUT = 10;

my $pid = open my $proc, '-|', "$cmd";

if (fork() == 0) {
    my $poor_mans_alarm = "sleep 1,kill 0,$pid ||exit for 1..$TIMEOUT;kill 9,$pid";
    # run poor man's alarm in a background process
    exec($^X, '-e', "$poor_mans_alarm");
}

my $process_output = "";
while (<$proc>) {
   $process_output .= $_;
}

如果你有这个代码的技巧或推荐一个完全不同的解决方案,请告诉我 .

谢谢和欢呼



Addition:

Got a working Example with IPC::Open3, But for future reader please Check out IPC::Run which has a Timeout Functionality included, as mentioned by James Green.

IPC :: Open3的工作示例:

my $pid = open3(\*WRITE, \*READ,\*ERROR,"$command");

if (fork() == 0) {
    my $poor_mans_alarm = "sleep 1,kill 0,$pid ||exit for 1..10;kill 9,$pid";
    # run poor man's alarm in a background process
    exec($^X, '-e', "$poor_mans_alarm");
}


# get all the STDOUT and STDERR from the Child.
while (<READ>) {
   $output .= $_;
}

while (<ERROR>) {
   $output .= $_;
}

waitpid($pid, 0);
if ($?) {
    $rc = $? >> 8;
    if ($rc != 1){
        print "Some error $?\n";
    }
}

1 回答

  • 0

    它看起来像 IPC::Run 几乎提供了你所追求的一切,包括STDOUT和STDERR的超时和捕获 . 文档位于https://metacpan.org/pod/IPC::Run,包括一些用法示例 .

相关问题