Запуск скрипта python с cron только в том случае, если он не запущен
мне нужно запустить скрипт python (job.py каждую минуту. Этот скрипт не должен запускаться, если он уже запущен. Время выполнения может быть от 10 секунд до нескольких часов.
поэтому я положил в свой crontab:
* * * * * root cd /home/lorenzo/cron && python -u job.py 1>> /var/log/job/log 2>> /var/log/job/err
чтобы избежать запуска скрипта, когда он уже запущен, я использую flock ().
это скрипт (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 ()
этот подход, кажется, работает.
Я ничего не упустил? Есть ли проблемы, с которыми я могу столкнуться, используя этот подход?
есть ли более рекомендуемые или" правильные " способы достижения этого поведения?
Я благодарю вас за любое предложение.
4 ответов
единственное предложение, которое я бы сделал, это сделать вашу обработку исключений немного более конкретной. Вы не хотите случайно удалить fcntl
импортировать один день и скрыть NameError
что результаты. Всегда старайтесь поймать наиболее конкретное исключение, которое вы хотите обработать. В этом случае я предлагаю что-то вроде:
import errno
try:
fcntl.lock(...)
except IOError, e:
if e.errno == errno.EAGAIN:
sys.stderr.write(...)
sys.exit(-1)
raise
таким образом, каких-либо другое причина блокировки недоступна появляется (вероятно, в вашей электронной почте, так как вы используете cron), и вы можете решить, если это то, на что должен смотреть администратор, еще один случай для обработки программы или что-то еще.
вы в беде, когда машина перезагружается или зависает с запущенным скриптом (и, следовательно, активной блокировкой). Простой способ противостоять этому-использовать @reboot
cron метка времени для запуска rm /path/to/lock
.
я столкнулся с этой точной проблемой на прошлой неделе, и хотя я нашел некоторые хорошие решения, я решил сделать очень простой и чистый пакет python и загрузил его в PyPI.
установить с: pip install quicklock
использование его чрезвычайно просто:
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> # Let's create a lock so that only one instance of a script will run
...
>>> singleton('hello world')
>>>
>>> # Let's try to do that again, this should fail
...
>>> singleton('hello world')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton
raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name()))
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python">
>>>
>>> # But if we quit this process, we release the lock automatically
...
>>> ^D
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> singleton('hello world')
>>>
>>> # No exception was thrown, we own 'hello world'!
взгляните:https://pypi.python.org/pypi/quicklock
можно использовать Контроллер Жира который является демоном, который перезапустит сценарий через X секунд после завершения предыдущего экземпляра, поэтому у вас никогда не может быть перекрывающихся экземпляров одного и того же сценария.
вы даже можете настроить его для запуска экземпляра сразу после этого, если выполняется определенное условие.
(Я боюсь, что сайт немного базовый, но проект стабилен и работает на нескольких веб-сайтах, о которых я знаю. Я сделаю хороший, красивый сайт, как только я получу v0.0.3 за дверь!)