在脚本运行期间关闭或禁止致命错误?

时间:2013-09-05 14:23:52

标签: perl

我们有一个while(1)脚本循环其各种工作,然后睡眠60秒然后再次完成它。该脚本需要全天候运行。

当我们在while(1)循环中添加新功能时,或者只是在随机问题的过程中添加新功能时,有时它们会失败并且不幸地崩溃整个脚本。解决方案已将所有此类函数包装在eval {}中,但我的问题是......无论如何全局设置所有错误或致命错误都不会停止/终止整个脚本,因此我们不必将所有内容包装在eval {}?

3 个答案:

答案 0 :(得分:3)

这没有任何意义。该计划如何知道在哪里恢复?你必须告诉它在哪里,然后你使用eval

对于记录失败并重新启动脚本的脚本,您肯定会更好地编写包装器。

答案 1 :(得分:3)

你要做的是 - 忽略任何错误,不惜一切代价继续 - 这是一个非常值得怀疑的做法,可能会使你的程序进入未定义的状态,并使实际的错误更难找到。

理论上可以覆盖CORE::GLOBAL::die子例程来捕获Perl代码中的异常,但真正的die仍然可用作CORE::die sub,这不会从XS代码或perl本身捕获错误(与使用eval不同)。请注意,某些模块使用diewarn作为控制流。请考虑以下代码:

sub foo {
  my ($x, $y) = @_;
  croak "X must be smaller than Y" unless $x < $y;
  return $y - $x;
}

现在,如果die成为warn,那么该函数可能会开始输出负数,从而造成各种破坏(例如,当用于数组索引时)。

,继续使用eval解决方案,甚至更好:迁移到Try::Tiny。存在致命错误的原因。


如果必须采用高可靠性,您可能希望采用类似Erlang的模型:工作流程池。如果出现错误,则该进程被终止,并且替换进程已开始。

答案 2 :(得分:2)

尽管有其他答案,但事实是某些错误可能不容易恢复,只是忽略它们并且跋涉很容易导致不必要的行为。另一个选择是删除while循环,以便脚本只执行一次,并从cron调用它,这允许您按计划运行程序。例如,您可以打开一个shell并调用crontab -e来编辑调度程序并添加以下行:

* * * * * perl /path/to/script.pl

将每分钟运行一次脚本并向您发送包含警告和错误的输出邮件。