繁体   English   中英

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

[英]Perl how to properly handle System Commands (including Timeout with Kill & capture of RC/STDERR/STDOUT)

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

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

我愿意接受任何形式的反馈。

我对命令执行的要求:

  • 超时->如果命令运行时间超过XX秒,则该命令应终止其进程
  • 如果命令返回信息,则不必等待超时结束
  • 我想在脚本中捕获退出状态,STDERR,STDOUT。

这是我从另一个stackoverflow问题得出的示例: 杀死一个挂起的子进程

目前对我不起作用的是:

  • 无法捕获已执行命令的退出状态
  • 无法捕获已执行命令的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 .= $_;
}

如果您对此代码有窍门或推荐一个完全不同的解决方案,请告诉我。

谢谢和欢呼



加成:

使用IPC :: Open3获得了一个有效的示例,但是对于以后的读者,请查看包含Timeout功能的IPC :: Run,如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";
    }
}

看起来IPC::Run提供了您所需要的几乎所有东西,包括超时以及STDOUT和STDERR的捕获。 文档位于https://metacpan.org/pod/IPC::Run,其中包括一些用法示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM