检查python脚本中运行的python脚本
我正在运行一个python脚本,完成这个脚本可能需要几个小时,也可能不需要几个小时 在python脚本的开头,我想检查这个python脚本是否已经在运行 如果它已经在运行,我想退出我刚刚启动的当前python 例如: python从凌晨1点开始,一直运行到凌晨3点 凌晨2点启动另一个,但不知道它已在运行。 我希望我的2AM python检查并退出,因为它已经在运行了 如何编写python检查python脚本中运行的python脚本,python,linux,unix,Python,Linux,Unix,我正在运行一个python脚本,完成这个脚本可能需要几个小时,也可能不需要几个小时 在python脚本的开头,我想检查这个python脚本是否已经在运行 如果它已经在运行,我想退出我刚刚启动的当前python 例如: python从凌晨1点开始,一直运行到凌晨3点 凌晨2点启动另一个,但不知道它已在运行。 我希望我的2AM python检查并退出,因为它已经在运行了 如何编写python 这就是我试图锁定的 try: l = lock.lock("/home/auto.py", tim
这就是我试图锁定的
try:
l = lock.lock("/home/auto.py", timeout=600) # wait at most 10 minutes
except error.LockHeld:
e = sys.exc_info()[0]
logging.error("Error: " + str(e) + " at main gatering Stats")
smtpObj.sendmail(sender, receivers, message + "Error: " + str(e) + " at main gatering stats")
exit("Fail: " + str(e) + " at main gathering Stats")
else:
l.release()
因此,我认为如果它仍在运行,将等待10分钟,然后退出。。如果不再运行,则运行当前python您可以尝试使用带有r
标志的命令重试指定次数,捕获调用的进程错误并退出,-p
标志将存储进程的pid
:
import os
import sys
from time import sleep
from subprocess import check_call, CalledProcessError
try:
check_call(["lockfile-create", "-q","-p", "-r", "0", "-l", "my.lock"])
except CalledProcessError as e:
print("{} is already running".format(sys.argv[0]))
print(e.returncode)
exit(1)
# main body
for i in range(10):
sleep(2)
print(1)
check_call(["rm","-f","my.lock"])
当一个脚本已经运行时,使用上面的代码运行test.py
脚本会输出以下内容:
$ python lock.py
lock.py is already running
4
选项
-q,--quiet
抑制任何输出。成功或失败仅由退出状态指示
-v,--verbose
启用诊断输出
-l,--lock name
不要将.lock附加到文件名。此选项适用于锁定文件创建、锁定文件删除、锁定文件触摸或锁定文件检查
-p,--使用pid
每当创建锁文件时,将当前进程id(PID)写入锁文件,并在检查锁的有效性时使用该PID。有关更多信息,请参阅锁定文件创建(3)手册页。此选项适用于锁定文件创建、锁定文件删除、锁定文件触摸和锁定文件检查
-o,--oneshot
触摸锁并立即退出。此选项适用于lockfile touch和mail touchlock。如果没有提供,这些命令将永远运行,每分钟触摸一次锁,直到被杀死
-r重试计数,--retry重试计数
在放弃之前,请尝试锁定文件名重试次数。每次尝试的延迟时间将比最后一次稍长(以5秒为增量),直到两次重试之间达到一分钟的最大延迟。如果未指定重试计数,则默认值为9,如果所有9次锁定尝试均失败,则在180秒(3分钟)后放弃
说明
lockfile_create函数以NFS安全的方式创建锁文件
如果flags设置为L_PID,那么lockfile_create不仅会检查现有的lockfile,还会读取内容,查看它是否包含ASCII格式的进程id。如果是,则锁定文件仅在该进程仍然存在时有效
如果锁文件位于共享文件系统上,则它可能是由远程主机上的进程创建的。因此,进程id检查是无用的,不应设置L_PID标志。在这种情况下,没有很好的方法来查看锁文件是否过时。因此,如果锁文件的时间超过5分钟,它将被删除。这就是为什么提供了lockfile_touch功能:在持有锁时,需要通过调用lockfile_touch()定期(每分钟左右)刷新锁
lockfile_check函数检查有效的锁文件是否已经存在,而不尝试创建新的锁文件
最后,lockfile_remove函数删除锁文件
用于以原子方式(甚至通过NFS)创建锁文件的算法如下所示:
一,
将创建一个唯一的文件。在printf格式中,文件名为.lk%05d%x%s。第一个参数(%05d)是当前进程id。第二个参数(%x)由时间(2)返回的值的4个小位组成。最后一个参数是系统主机名
二,
然后使用链接(2)创建锁文件。链接的返回值被忽略
三,
现在锁文件是stat()ed。如果stat失败,我们转到步骤6
四,
将lockfile的stat值与临时文件的stat值进行比较。如果它们是一样的,我们有锁。将删除临时文件,并将值0(成功)返回给调用者
五,
检查现有锁文件是否有效。如果无效,则删除过时的锁文件
六,
在重试之前,我们先睡n秒钟。n最初为5秒,但在每次重试后,5秒加起来最多为60秒(增量退避)。然后我们进入第2步,返回重试次数
似乎有一个等价的包名为redhat
在mac上,您可以使用并执行以下操作:
import os
import sys
from time import sleep
import os
from subprocess import Popen, CalledProcessError, check_call
p = Popen(["lockfile", "-r", "0", "my.lock"])
p.wait()
if p.returncode == 0:
with open("my.pid", "w") as f:
f.write(str(os.getpid()))
else:
try:
with open("my.pid") as f:
# see if process is still running or lockfile
# is left over from previous run.
r = f.read()
check_call(["kill", "-0", "{}".format(r)])
except CalledProcessError:
# remove old lock file and create new
check_call(["rm", "-f", "my.lock"])
check_call(["lockfile", "-r", "0", "my.lock"])
# update pid
with open("my.pid", "w") as out:
out.write(str(os.getpid()))
print("Deleted stale lockfile.")
else:
print("{} is already running".format(sys.argv[0]))
print(p.returncode)
exit(1)
# main body
for i in range(10):
sleep(1)
print(1)
check_call(["rm", "-f", "my.lock"])
在您的情况下,使用套接字可能会起作用:
from socket import socket, gethostname, error, SO_REUSEADDR, SOL_SOCKET
from sys import argv
import errno
sock = socket()
# Create a socket object
host = gethostname()
# /proc/sys/net/ipv4/ip_local_port_range is 32768 61000 on my Ubuntu Machine
port = 60001
# allow connection in TIME_WAIT
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
try:
sock.bind((host, port))
sock.connect((host, port))
except error as e:
# [Errno 99] Cannot assign requested address
if e.errno == errno.EADDRNOTAVAIL:
print("{} is already running".format(argv[0]))
exit(1)
# else raise the error
else:
raise e
# main body
from time import sleep
while True:
print(1)
sleep(2)
sock.close()
这与@PadraicCunningham有什么不同?我尝试了大多数答案,但要么不起作用,要么我无法让它工作。一个锁文件不起作用?我尝试了锁文件,因为它是投票最多的。。我不确定是不是我的编码不起作用。。我无法让它工作。你应该为此创建一个临时锁文件。检查锁文件,然后退出或其他什么。那么这将在第一个python上运行,并在scond python上退出?同样在heck_调用([“lockfile create”、“-r”、“3”、“--lock name”、“my.lock”])
什么是--lock name
和my.lock
?这只是我可以创建的任何名称吗?@Tim,名称可以是任何名称,它是在脚本运行时创建的。请使用我提供的回溯示例(最近一次调用):check_call([“lockfile create”、“-r”、“3”、“--lock name”、“my.lock”])File“/usr/lib64/python2.7/subprocess.py”,第537行,check_call retcode=call(*popenargs,**kwargs)File“/usr/lib64/python2.7/subprocess.py”,第524行,在调用返回Popen(*popenargs,**kwargs.wait()文件“/usr/lib64/python2.7中