【问题标题】:Circumstances under which die() does not exit a Perl script?在哪些情况下 die() 不会退出 Perl 脚本?
【发布时间】:2011-07-13 22:19:23
【问题描述】:

我正在调试一个长时间运行的 Perl 脚本的非常奇怪的问题。

问题是脚本没有按预期在die() 上退出。相反,脚本只是挂起而不返回。

我自己没有定义任何错误处理程序,所以我假设die() 会导致脚本立即终止。

这是脚本的基本结构和使用的模块:

#!/usr/bin/perl

use strict;
use utf8;
use warnings;

use DBI; # with MySQL driver ("dbi:mysql:database=...")
use Geo::IP;
use POSIX;
use URI::Escape;

open(COMMAND, 'command_line |');
while (<COMMAND>) {
    #
    # .. stuff that can go wrong ..
    #
    die("I'm expecting the script to terminate here. It doesn't.") if ($gone_wrong);
}
close(COMMAND);

对这种行为的解释是什么?是否有任何已知用于设置错误处理程序的模块可以解释挂在die() 上的脚本?

【问题讨论】:

  • 在您的die() 调用之前添加一个调试行:warn "DIE = $SIG{__DIE__}" 以查看当时是否存在模具处理程序。
  • 什么是'command_line'程序?你在循环内使用mysql DBI连接吗?
  • 您看到die 消息了吗?你的问题没有说清楚。如果没有,在它之前添加warn 会显示您是否真的到达die。如果这看起来很明显,我们深表歉意!
  • 核心:command_line 程序是一个普通的 Linux 应用程序,它写入 STDOUT。没有什么比通过管道编写的更能与 Perl 脚本交互了。循环内部使用了mysql DBI连接,是的。
  • 您确定满足 $gone_wrong 条件吗?就像其他人所说的那样,在其中添加一个警告/打印语句以查看。这些应该独立于任何 DIE 处理程序发生。

标签: perl


【解决方案1】:

好吧,END 块和对象析构函数仍然在 die 之后调用。如果其中一个挂起(或执行需要很长时间的操作),则脚本不会立即退出。但这应该发生在 打印来自 die 的消息之后(除非 STDERR 被缓冲,因此您不会立即看到该消息)。

您提到了 DBI,因此您可能有一个正在调用其析构函数的数据库句柄。 (不过,我不确定这是否是问题所在。)

【讨论】:

    猜你喜欢
    • 2016-09-01
    • 2014-12-10
    • 2016-07-30
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 2023-04-02
    相关资源
    最近更新 更多