【问题标题】:How can I prevent an error in my Perl script from terminating the script?如何防止我的 Perl 脚本中的错误终止脚本?
【发布时间】:2010-11-19 21:22:46
【问题描述】:

我有一个简单的 Perl 脚本,它使用无限循环作为 Linux 守护程序运行。它每 10 秒连接到一个数据库以执行一个进程。

while (1)
{
    # THIS LINE WILL KILL THE SCRIPT IF IT FAILS
    my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password");
    . . . do something . . .
    sleep (10);
}

我有两个问题:

  • 如果数据库不可用,如何保持脚本运行?
  • 我可以添加异常处理程序来向我发送电子邮件或记录错误吗?

【问题讨论】:

  • 注意:您的脚本并非每十秒连接一次。如果平均连接需要 1 秒,那么您的脚本(平均)每 11 秒连接一次。
  • 如果你不知道,我不会告诉你的。 :)

标签: linux perl exception-handling daemon


【解决方案1】:

这会尝试每隔 10 秒连接一次,而不是每 10 秒一次,正如 William Pursell 所说:

while (1)
{
    # THIS LINE WILL KILL THE SCRIPT IF IT FAILS
    my $DB;
    eval { 
        $DB = DBI->connect("dbi:Sybase:server=myserver","user","password");
    };
    if ( my $ex = $@ ) {
        warn $ex;
        next;
    }
    # do something with $DB
    continue {
        sleep 10;
    }
}

另请参阅Object Oriented Exception Handling in Perl, is it worth it? 和 How can I cleanly handle error checking in Perl?

【讨论】:

  • 我认为您不想在 eval 块中重新声明我的 $DB。
  • @xcramps 感谢您的关注并告诉我。
【解决方案2】:

我有点疑惑:

   my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password");

如果无法连接,通常不会死机。通常它应该返回一个错误代码 而不是一个数据库句柄。只有当你使用 RaisError 时,它才会死掉/抛出异常。

   my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password", 
                        { RaiseError => 1});

见DBI man-page

【讨论】:

    【解决方案3】:

    来自Programming Perl:

    sub try (&@) {
         my($try,$catch) = @_;
         eval { &$try };
         if ($@) {
             local $_ = $@;
             &$catch;
         }
    }
    sub catch (&) { $_[0] }
    
    try {
        die "phooey";
    } catch {
        /phooey/ and print "unphooey\n";
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-05
      • 2018-01-26
      • 2018-02-08
      • 2012-01-10
      • 2011-12-10
      • 2010-10-07
      • 2020-08-02
      • 1970-01-01
      相关资源
      最近更新 更多