我们有一个while(1)脚本循环其各种工作,然后睡眠60秒然后再次完成它。该脚本需要全天候运行。
当我们在while(1)循环中添加新功能时,或者只是在随机问题的过程中添加新功能时,有时它们会失败并且不幸地崩溃整个脚本。解决方案已将所有此类函数包装在eval {}中,但我的问题是......无论如何全局设置所有错误或致命错误都不会停止/终止整个脚本,因此我们不必将所有内容包装在eval {}?
答案 0 :(得分:3)
这没有任何意义。该计划如何知道在哪里恢复?你必须告诉它在哪里,然后你使用eval
。
对于记录失败并重新启动脚本的脚本,您肯定会更好地编写包装器。
答案 1 :(得分:3)
你要做的是 - 忽略任何错误,不惜一切代价继续 - 这是一个非常值得怀疑的做法,可能会使你的程序进入未定义的状态,并使实际的错误更难找到。
理论上可以覆盖CORE::GLOBAL::die
子例程来捕获Perl代码中的异常,但真正的die
仍然可用作CORE::die
sub,这不会从XS代码或perl本身捕获错误(与使用eval
不同)。请注意,某些模块使用die
和warn
作为控制流。请考虑以下代码:
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
将每分钟运行一次脚本并向您发送包含警告和错误的输出邮件。