脚本停止工作后如何保证文件删除?

时间:2016-11-01 12:16:08

标签: python process pid

我每小时都有一个由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)

但是经过一段时间脚本停止工作后,当我看到“ps aux | grep python”时,我没有看到这个脚本作为进程,但我确实在这个地方看到了文件。 当我手动运行脚本时,我会在屏幕上看到迭代打印的信息,但过了一段时间后,我看到“已终止”这个词,脚本已退出,文件仍在该位置。

如何保证脚本停止工作后100%删除文件?

谢谢!

2 个答案:

答案 0 :(得分:0)

通常您可以使用atextit模块功能,但在您的情况下(意外终止)它也可能无效。

mkstemp语句中使用with(指定所需的程序后缀/ refix)可能会有效:它会在/tmp中创建唯一的pidfile并在with时清除它块完成或终止。

答案 1 :(得分: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()

同样,由于可能的pid冲突,提供的代码不是100%安全的。通过添加ps命令输出的解析,可以使运行过程的验证更加复杂。尝试找到具有所需pid值的行,并检查它是否与crontab条目类似。