我有一个应该无限期运行的 perl 脚本。它被终止了...我如何确定是谁或什么终止了它?

我有一个应该无限期运行的 perl 脚本。它被终止了...我如何确定是谁或什么终止了它?

我在屏幕上运行 perl 脚本(我可以登录并检查调试输出)。脚本逻辑中的任何内容都无法将其完全杀死。

我是仅有的两个有权访问该服务器的人之一,另一个人发誓说不是他(我们俩都投入了不少资金,希望服务器能继续顺利运行)。我没有理由相信有黑客设法获得了 shell 或类似的东西。我几乎没有理由怀疑主机操作的管理员(就带宽/CPU 而言,这个脚本非常轻量级)。

Screen 继续运行,但在 perl 脚本输出的末尾我看到了“Killed”,并且它已返回到提示符。我该如何测试到底是什么在破坏这个该死的东西?

我检查了 crontab,里面没有任何可以终止随机/非随机进程的内容。任何日志文件中都没有任何提示。它似乎会运行 2 到 8 小时(在我家里的 Mac 上,它可以运行超过 24 小时而不会出现问题)。服务器正在运行 Ubuntu 版本或其他版本,如果重要的话我可以查找一下。

答案1

在没有太多实际知识的情况下,我会开始查看 dmesg 输出或各种系统日志,看看 OOM killer 是否正在运行。如果是这样,那可能就是它了。

答案2

为所有信号(TERM、SEGV、INT、HUP 等)添加信号处理程序,并让它们在被触发时注销。它不会告诉您发送信号的人,但可以让您看到它是什么信号,并可能忽略它。

$SIG{'TERM'} = $SIG{'INT'} = sub { print(STDERR "Caught SIG$_[0]. Ignoring\n"); };

当它捕获到 sigterm 或 sigint 时,它将打印出来,然后将控制权返回给程序。当然,由于所有这些信号都被忽略,因此终止它的唯一方法是让程序本身退出,或者向它发送无法捕获的 SIGKILL。

答案3

我知道这并不是您问题的确切答案,所以如果它有些离题,我深表歉意,但是:您的应用程序真的需要永远连续运行吗?Perl 不是世界上最节省资源的环境,虽然解释器启动的开销并非没有缺点,但运行时间极长的脚本可能会有自己的麻烦 - 内存泄漏(通常在您无法控制的水平)是 vanilla-perl 开发人员的祸根,这就是为什么人们经常通过在更正式的资源节约主义子环境(如 Perl::POE)中运行来缓解这些问题,或者通过将长时间运行的侦听器部分交给前端服务(如 xinetd)并仅在需要完成工作时执行 perl 组件来缓解这些问题。

我运行了几个 perl 脚本,它们连续读取和处理我们(相当大的)中央系统日志流的输出;它们一直受到可怕的、无法解释的“尽管修剪了哈希键,但没有释放内存”问题的困扰,并且需要由更适合连续大量输入的东西(例如,像 Gearman 这样的事件队列)进行前端处理,所以我们可以将 perl 留给它最擅长的数据处理任务。

说了这么多,我真的很抱歉。希望这至少能对你有所帮助!

答案4

您可能遇到了资源限制。例如 CPU 时间。尝试ulimit -a检查。如果它只是登录脚本中设置的软限制,那么您可以使用例如 来修复它ulimit -t unlimited。如果它是硬限制,例如为 OpenBSD 和其他操作系统上的普通用户设置的硬限制,那么您必须覆盖它。

相关内容