2016-11-01 10 views
1

У меня есть скрипт, выполняемый crontab каждый час и взаимодействующий с API (синхронизация базы данных). Обычно это займет один час или около того, и я проверить при следующем запуске, если этот процесс до сих пор в памяти или нет:Как гарантировать удаление файла после того, как скрипт перестает работать?

#/usr/bin/env python 

import os 
import sys 

pid = str(os.getpid()) 
pidfile = "/tmp/mydaemon.pid" 

if os.path.isfile(pidfile): 
    print "%s already exists, exiting" % pidfile 
    sys.exit() 
file(pidfile, 'w').write(pid) 
try: 
    # Do some actual work here 
finally: 
    os.unlink(pidfile) 

но через некоторое время скрипт перестал работать, когда я смотрю на «пс Окс | Grep python ", я не вижу этот сценарий как процесс, но я вижу файл на месте. И когда я запускаю скрипт вручную, я вижу, что информация напечатана итеративно на экране, но через некоторое время я вижу слово «Terminated», сценарий завершен и файл все еще находится на месте.

Как обеспечить 100% удаление файла после того, как скрипт перестает работать?

Спасибо!

ответ

0

Обычно вы можете использовать функциональность модуля atextit, но в вашем случае (неожиданное завершение) оно также может не работать.

Возможно использование mkstemp (с указанием требуемой программой суффикса/refix) внутри with заявления может работать: это создаст уникальный PIDFILE в /tmp и очистить его, когда with блока завершается или завершается.

0

Похоже, что ваш скрипт неожиданно завершен, скорее всего из-за слишком большого использования памяти. Не гарантируется, что finally будет выполнен при неожиданном завершении программы. Поэтому, прежде всего, я предлагаю вам найти причину неожиданного завершения исправить.

На самом деле нет 100% -го способа гарантировать, что файл будет удален. Тем не менее, есть несколько обходных решений для обработки оборванных файлов pid.

Разместите файлы pid на томе /var/run, поэтому они будут удалены при неожиданном перезапуске системы.

Проверить кастрированный баран процесс с таким PID все еще работает на каждом выполнении сценария:

import os 

def is_alive(pid): 
    try: 
     os.kill(pid, 0) # do nothing but throws an exception 
     return True 
    except OSError: 
     return False 

# and add this to your code: 
if os.path.isfile(pidfile): 
    with open(pidfile) as f: 
     if is_alive(f.read()): 
      sys.exit() 

Опять же, при условии, код не является 100% гарантией безопасности из-за возможных Pid столкновений. Вы можете сделать проверку запущенного процесса более сложной, добавив синтаксический анализ вывода команды ps. Попробуйте найти строку с желаемым значением pid и проверьте, похоже ли она похожа на вашу запись crontab.