Perl TIMEOUT输出消息

时间:2016-06-15 16:01:47

标签: perl timeout output alarm nagios

我正在编写perl脚本以使用Nagios监视数据库。 我使用Time :: HiRes库中的闹钟功能进行超时。

use Time::HiRes qw[ time alarm ];
alarm $timeout;

一切正常。问题是我想要更改输出消息,因为它返回" Temporizador"如果我做了

echo $?

返回142.我想更改消息以使"退出3"所以它可以被Nagios认可。

已经尝试过' eval'但是没有用。

2 个答案:

答案 0 :(得分:3)

您应该处理ALRM信号。例如:

#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[ time alarm ];

$SIG{ALRM} = sub {print "Custom message\n"; exit 3};

alarm 2;
sleep 10; # this line represents the rest of your program, don't include it

这将输出:

18:08:20-eballes@urth:~/$ ./test.pl 
Custom message
18:08:23-eballes@urth:~/$ echo $?
3

有关处理信号的扩展说明,请检查this nice tutorial on perltricks

答案 1 :(得分:3)

花费时间的功能是用C语言编写的,这使您无法安全地使用自定义信号处理程序。

您似乎并不担心会强行终止您的程序,因此我建议您使用alarm而不使用信号处理程序来强制终止程序,如果运行时间过长,并使用包装器提供对Nagios的正确回应。

更改

/path/to/program some args

/path/to/timeout_wrapper 30 /path/to/program some args

以下是timeout_wrapper

#!/usr/bin/perl
use strict;
use warnings;

use POSIX       qw( WNOHANG );
use Time::HiRes qw( sleep time );

sub wait_for_child_to_complete {
   my ($pid, $timeout) = @_;
   my $wait_until = time + $timeout;
   while (time < $wait_until) {
      waitpid($pid, WNOHANG)
         and return $?;

      sleep(0.5);
   }

   return undef;
}

{
   my $timeout = shift(@ARGV);

   defined( my $pid = fork() )
      or exit(3);

   if (!$pid) {
      alarm($timeout);   # Optional. The parent will handle this anyway.
      exec(@ARGV)
         or exit(3);
   }

   my $timed_out = 0;
   my $rv = wait_for_child_to_complete($pid, $timeout);
   if (!defined($rv)) {
      $timed_out = 1;
      if (kill(ALRM => $pid)) {
         $rv = wait_for_child_to_complete($pid, 5);
         if (!defined($rv)) {
            kill(KILL => $pid)
         }
      }
   }

   exit(2) if $timed_out;
   exit(3) if $rv & 0x7F;  # Killed by some signal.
   exit($rv >> 8);         # Expect the exit code to comply with the spec.
}

使用Nagios Plugin Return Codes。超时应该实际返回2