![使用“while true”来保持脚本存活是一个好主意吗?](https://linux22.com/image/62102/%E4%BD%BF%E7%94%A8%E2%80%9Cwhile%20true%E2%80%9D%E6%9D%A5%E4%BF%9D%E6%8C%81%E8%84%9A%E6%9C%AC%E5%AD%98%E6%B4%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A5%BD%E4%B8%BB%E6%84%8F%E5%90%97%EF%BC%9F.png)
我刚刚从另一个世界跳入 UNIX,想知道是否
while true
do
/someperlscript.pl
done
Perl 脚本本身内部有一个文件夹/文件监视程序,当文件在目标位置发生更改时执行。
这是while true
一个好主意吗?如果不是,首选的稳健方法是什么?
TIA
编辑:由于这似乎引起了相当大的兴趣,因此这是完整的场景。 Perl 脚本本身使用文件监视程序监视目录。收到新文件(它们通过 rsync 到达)后,它会选取新文件并进行处理。现在传入的文件可能已损坏(不要问..来自树莓派),有时该进程可能无法处理它。我不知道具体原因,因为我们还不知道所有的情况。
但是 - 如果该进程确实由于某种原因失败,我们希望它启动并运行并处理下一个文件,因为下一个文件与可能导致错误的前一个文件完全无关。
通常我会使用某种 catch all 并将整个代码包裹在它周围,这样它就永远不会崩溃。但对 perl 不确定。
据我了解,使用像supervisord这样的东西是一个很好的方法。
答案1
这取决于 perl 脚本返回的速度。如果它返回得很快,您可能需要在执行之间插入一个小暂停以避免 CPU 负载,例如:
while true
do
/someperlscript.pl
sleep 1
done
如果未找到脚本或立即崩溃,这还可以防止 CPU 占用。
循环也最好在 perl 脚本本身中实现以避免这些问题。
编辑:
当您编写循环时,唯一的目的是在 Perl 脚本崩溃时重新启动它,更好的方法是将其实现为受监视的服务,但精确的方法取决于操作系统。例如:Solaris smf、Linux systemd 或基于 cron 的重启程序。
答案2
关于使用的其他答案inotify
是正确的,但不是这个问题的答案。
进程管理器(例如supervisord
、upstart
、 或runit
)专门针对监视服务崩溃并重新启动服务的问题而设计。
您的发行版可能带有内置的进程管理器。
答案3
while true
作为通用的“永远循环”结构是很好的。正如其他答案所说,循环体不应该为空,或者由于循环内的命令不起作用而变为空。
如果您使用的是 Linux,您可能需要使用类似 的命令inotifywait
,这使得while
循环更加简单:
while inotifywait -qqe modify "$DIRECTORY"
do
process_the_directory "$DIRECTORY"
done
在这里,该inotifywait
命令将等待文件系统事件发生(在本例中,当目录中的文件被写入时)。此时,它成功退出并执行循环体。然后它再次返回等待。因为该inotifywait
命令等待目录中发生某些事情,所以它比不断轮询目录要高效得多。
答案4
当你的 Perl 脚本想要一直运行时,为什么要使用 while 结构?当 Perl 由于某些严重问题而失败时,同时启动的新 Perl 脚本可能会同样严重崩溃。一次又一次等等。
如果您确实希望重新启动 Perl,请考虑 crontab 和一个首先检查正在运行的实例的脚本。这样,您的脚本甚至可以在重新启动后启动。