【问题标题】:Cleanup in END functionEND 函数中的清理
【发布时间】:2013-01-11 11:48:42
【问题描述】:

我的 perl 脚本使用 END 函数来取消链接一些临时文件。有时脚本会被用户中断或挂起,而临时文件不会被删除。

在 perl 中处理这个问题的程序是什么?除非脚本完全运行或执行 exit 或 die,否则 end 函数不起作用。

谢谢

【问题讨论】:

    标签: perl


    【解决方案1】:

    这里有两个方面。第一个是如果您的程序或多或少干净地完成,则清理临时文件。为此,您不必重新发明轮子,只需使用核心模块File::Temp。它可以做很多事情,它的好处之一是它可以在变量被垃圾回收时删除临时文件。

    另一方面是如果发生真正的程序崩溃(例如kill -9)。在这种情况下,您的程序无法自行处理清理工作。您必须依靠操作系统来为您执行此操作。例如,几个 Linux 发行版会定期清理 /tmp/var/tmp。您还可以为您编写一个 cron 作业来帮助您。

    但是请注意,并非所有 Linux 发行版都在 /tmp(或 /var/tmp)中进行清理。其他人只在启动过程中这样做。在机器运行时这样做有潜在的危险(程序仍在使用的文件可能会被意外删除)。有像 tmpreaper 这样的工具可以帮助你。

    如果您想要一种相当简单的方法,那么我建议您既不要使用/tmp 也不要使用/var/tmp,而是使用其中一个下的您自己的子目录,并使用tmpreaper 之类的工具来清理该目录。这样您就可以适度确定只有您程序的临时文件(而不是其他程序的临时文件)受到清理的影响。

    【讨论】:

    • 谢谢,我没有考虑 /tmp。我将文件存储在那里。
    【解决方案2】:

    END {} 块仅在 Perl 本身决定退出时运行。如果它因SIGTERMSIGINT 而退出(因为有人在终端上按下了Ctrl+C),那么该块将不会运行。

    无论如何,你都可以捕捉到这两个信号和exit,从而导致 Perl 来处理它。您可以安装信号处理程序:

    $SIG{TERM} = $SIG{INT} = sub { exit 1 };
    

    SIGKILL 对死亡无能为力,但这应该很少见。

    【讨论】:

      【解决方案3】:

      在 unix 系统上,如果文件在被删除之前打开,您仍然可以在文件被删除后使用该文件。如果您实际上并不需要文件名(或者如果您可以调整代码以便不需要),这是最可靠的解决方案。 File::Temp 的部分功能会为您预先删除临时文件。

      【讨论】:

        【解决方案4】:

        如果发生真正的程序中断(例如,kill -9 或 Ctrl+C),您可以指定程序应如何处理它。

        搜索 %SIG here 你会找到一个例子。

        【讨论】:

        • 您不能在程序中处理SIGKILL(即kill -9)。你可以处理普通的killSIGTERM)。
        猜你喜欢
        • 1970-01-01
        • 2012-06-28
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        • 2022-01-07
        • 2020-04-09
        • 2020-09-12
        • 1970-01-01
        相关资源
        最近更新 更多