【问题标题】:Perl : Implement timeout (& kill) for process invoked via backticksPerl:为通过反引号调用的进程实现超时(和终止)
【发布时间】:2017-10-31 08:58:34
【问题描述】:

我正在尝试实现一个例程,该例程将接受“命令”和相关的“超时”。 如果命令在指定时间内完成,它应该返回输出。 否则 - 它应该终止进程。

sub runWithTimeout {

   my ($pCommand,$pTimeOut) = @_;
   my (@aResult);

   print "Executing command [$pCommand] with timeout [$pTimeOut] sec/s \n";
   eval {
        local $SIG{ALRM} = sub { die "alarm\n" };
        alarm $pTimeOut;
        @aResult = `$pCommand`;
        alarm 0;
   };
   if ($@) {
        print("Command [$pCommand] timed out\n");
        # Need to kill the process.However I don't have the PID here.
        # kill -9 pid
    } else {
        print "Command completed\n";
        #print Dumper(\@aResult);
    }
}

示例调用:

&runWithTimeout('ls -lrt',5);

Executing command [ls -lrt] with timeout [5] sec/s 
Command completed


&runWithTimeout('sleep 10;ls -lrt',5);

Executing command [sleep 10;ls -lrt] with timeout [5] sec/s 
Command [sleep 10;ls -lrt] timed out

猜猜我是否有 PID - 我可以在 if 块中对 PID 使用“kill”。

任何关于如何获得 PID(或任何其他更好的方法)的指针 - 这将是一个很大的帮助。

【问题讨论】:

  • 也许在 perl 中不这样做会更容易,而是使用timeout 命令来代替?
  • 最简单的IPC::Run

标签: perl timeout kill-process backticks


【解决方案1】:

不要运行带有反引号的命令,而是使用open。对于奖励积分 - 使用 IO::Selectcan_read 看看你是否有任何输出:

use IO::Select; 
my $pid = open ( my $output_fh, '-|', 'ls -lrt' );
my $select = IO::Select -> new ( $output_fh ); 
while ( $select -> can_read ( 5 ) ) { 
    my $line = <$output_fh>;
    print "GOT: $line"; 
}
##timed out after 5s waiting.  
kill 15, $pid;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多