仅当未运行时才使用 cron 运行 python 脚本
我需要每分钟运行一个 python 脚本(job.py)。如果该脚本已在运行,则不得启动该脚本。其执行时间可以在10秒到几个小时之间。
所以我在我的 crontab 中输入:
* * * * * root cd /home/lorenzo/cron && python -u job.py 1>> /var/log/job/log 2>> /var/log/job/err
为了避免在脚本已经运行时启动脚本,我使用了 fancy() 。
这是脚本(job.py):
import fcntl
import time
import sys
def doIncrediblyImportantThings ():
for i in range (100):
sys.stdout.write ('[%s] %d.\n' % (time.strftime ('%c'), i) )
time.sleep (1)
if __name__ == '__main__':
f = open ('lock', 'w')
try: fcntl.lockf (f, fcntl.LOCK_EX | fcntl.LOCK_NB)
except:
sys.stderr.write ('[%s] Script already running.\n' % time.strftime ('%c') )
sys.exit (-1)
doIncrediblyImportantThings ()
这种方法似乎有效。
我有什么遗漏的吗?使用这种方法会遇到什么麻烦吗?
是否有更多建议或“适当”的方法来实现这种行为?
我感谢你的任何建议。
I need to run a python script (job.py) every minute. This script must not be started if it is already running. Its execution time can be between 10 seconds and several hours.
So I put into my crontab:
* * * * * root cd /home/lorenzo/cron && python -u job.py 1>> /var/log/job/log 2>> /var/log/job/err
To avoid starting the script when it is already running, I use flock().
This is the script (job.py):
import fcntl
import time
import sys
def doIncrediblyImportantThings ():
for i in range (100):
sys.stdout.write ('[%s] %d.\n' % (time.strftime ('%c'), i) )
time.sleep (1)
if __name__ == '__main__':
f = open ('lock', 'w')
try: fcntl.lockf (f, fcntl.LOCK_EX | fcntl.LOCK_NB)
except:
sys.stderr.write ('[%s] Script already running.\n' % time.strftime ('%c') )
sys.exit (-1)
doIncrediblyImportantThings ()
This approach seems to work.
Is there anything I am missing? Are there any troubles I can run into using this approach?
Are there more advised or "proper" ways of achieving this behaviour?
I thank you for any suggestion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我唯一的建议是让你的异常处理更加具体一些。您不想有一天意外删除
fcntl
导入并隐藏由此产生的NameError
。始终尝试捕获您想要处理的最具体的异常。在这种情况下,我建议类似:这样,任何导致无法获取锁定的其他原因都会显示出来(可能会在您的电子邮件中,因为您使用的是 cron),您可以决定这是否适合管理员看看,程序要处理的另一种情况,或者其他什么。
The only suggestion I would make is to make your exception handling a little more specific. You don't want to accidentally delete the
fcntl
import one day and hide theNameError
that results. Always try to catch the most specific exception you want to handle. In this case, I suggest something like:This way, any other cause of the lock being unobtainable shows up (probably in your email since you're using cron) and you can decide if it's something for an administrator to look at, another case for the program to handle, or something else.
当机器重新启动或在脚本运行时冻结(因此是活动锁)时,您就会遇到麻烦。解决这个问题的简单方法是使用 @reboot cron 时间戳来运行 rm /path/to/lock。
You're in trouble when the machine reboots or freezes with the script running (and thus an active lock). Simple way to counter this is to use the
@reboot
cron timestamp to runrm /path/to/lock
.上周我遇到了这个问题,虽然我确实找到了一些好的解决方案,但我决定制作一个非常简单干净的 python 包并将其上传到 PyPI。
安装方式:
pip install Quicklock
使用它非常简单:
看一下:https: //pypi.python.org/pypi/quicklock
I ran into this exact problem last week, and although I did find some good solutions, I decided to make a very simple and clean python package and uploaded it to PyPI.
Install with:
pip install quicklock
Using it is extremely simple:
Take a look: https://pypi.python.org/pypi/quicklock