检查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

我正在运行一个python脚本,完成这个脚本可能需要几个小时,也可能不需要几个小时

在python脚本的开头,我想检查这个python脚本是否已经在运行

如果它已经在运行,我想退出我刚刚启动的当前python

例如:

python从凌晨1点开始,一直运行到凌晨3点 凌晨2点启动另一个,但不知道它已在运行。 我希望我的2AM python检查并退出,因为它已经在运行了

如何编写python


这就是我试图锁定的

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中