繁体   English   中英

当另一个python脚本正在运行时,如何停止我的python脚本?

[英]How can I stop my python script when another python script is running?

我想知道当当前的python脚本已经运行时如何停止它。

为了清楚起见,我想用我自己的python脚本编写它。 因此,在main方法中,第一件事将检查我的python脚本是否已在运行。 如果它正在运行,我想退出并显示一条错误消息。

目前,我正在尝试以下代码:

if os.system("ps ax | grep sample_python.py") == True:
     print "fail"
     exit(0)
else:
     print "pass"

上面的代码看起来像是grep的python名称..但它总是转到else循环,而不是进入if循环并退出。

因此,出于测试目的,我运行脚本,然后在另一个终端上再次运行脚本。 第一个脚本不会停止,但是第二个python不会进入if循环以打印出错误消息。

我怎样才能解决这个问题?


好吧,我发现了一个愚蠢的东西,我想看看是否有人可以帮助我解决这个问题。.所以我的意思是,如果当前正在运行另一个python,则杀死刚刚启动的python。正在运行我的python并在此python内部运行检查代码..它将始终退出..因为因为一旦启动python PID就会被创建并正在运行...

所以.. python开始-> pid已创建并正在运行->检查python是否正在运行->是python正在运行->退出。

我想看看是否有一种方法可以让python启动->检查python是否已经在运行->如果它正在运行,请杀死当前的python而不是正在运行的python。

正在运行的进程的带有PID的锁文件是一种更系统的方法。 程序只是在开始时检查PID文件是否同时存在并被锁定( flocklockf ); 如果是这样,则意味着该程序的另一个实例仍在运行。 如果不是,它将创建(或重写)PID文件并将其锁定。

flock / lockf锁的优点是,在程序终止的情况下,操作系统会自动删除该锁。

查看此处如何在Python中执行此操作:

Python:用于创建基于PID的锁定文件的模块?

os.system()返回已运行命令的退出值。 如果ps成功,则返回0,这不等于True。 您可以显式测试命令是否返回零,这将使您进入if块。

编辑:为此需要os.subprocess 这四个命令应该可以得到您想要的。

p1 = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'bash'], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['wc', '-l'], stdin=p2.stdout, stdout=subprocess.PIPE)
count = int(p3.stdout.read())
if count > 1:
    print('yes')

用脚本名称替换“ bash”。 这是获取正在运行的进程的列表,输出到grep的管道将winnow除去您的脚本(或代码示例中的bash实例),输出到wc的管道以获取行数,然后询问该进程其标准输出是当前正在运行的脚本实例的计数。 然后,可以在if语句中使用该count变量,如果有多个实例在运行,则可以中止运行。

更多pythonic方式:

import os
import psutil

script_name = os.path.basename(__file__)
if script_name in [p.name() for p in psutil.get_process_list()]:
   print "Running"

而不是使用grep ,为什么不创建一个锁定文件? 程序的一个实例在已知位置创建一个文件,并在退出时将其删除。 任何其他实例都必须检查该文件是否存在,并且应该仅在文件已存在的情况下继续运行。

os.open()函数对此具有特定的标志:

import os

LOCKFILE_LOCATION = "/path/to/lockfile"

try:
    os.open(LOCKFILE_LOCATION, os.O_CREAT|os.O_WRONLY|os.O_EXCL)
    # Maybe even write the script's PID to this file, just in case you need
    # to check whether the program died unexpectedly.
except OSError:
    # File exists or could not be created. Can check errno if you really
    # need to know, but this may be OS dependent.
    print("Failed to create lockfile. Is another instance already running?")
    exit(1)
else:
    print("Pass")
    # Run the rest of the program.
    # Delete the file
    os.remove(LOCKFILE_LOCATION)

通过import time; time.sleep(20)来进行尝试import time; time.sleep(20) 在print(“ Pass”)之后运行import time; time.sleep(20)并运行该脚本的多个实例; 除了一个人以外的所有人都应该失败。

您可以使用跨平台库psutil遍历进程,解析每个进程的命令行,并检查它是否是具有相同脚本路径的python进程,然后您可以在仅找到一个脚本时停止执行, 或者杀死/停止执行旧实例并继续使用新实例。

import os
import psutil
import sys

for proc in psutil.process_iter():
    if "python" in proc.name():
        if len(proc.cmdline()) > 1:
            script_path = sys.argv[0]
            proc_script_path = proc.cmdline()[1]
            if script_path.startswith("." + os.sep) or script_path.startswith(".." + os.sep):
                script_path = os.path.normpath(os.path.join(os.getcwd(), script_path))
            if proc_script_path.startswith("." + os.sep) or proc_script_path.startswith(".." + os.sep):
                proc_script_path = os.path.normpath(os.path.join(proc.cwd(), proc_script_path))
            if  script_path == proc_script_path and os.getpid() != proc.pid:
                #proc.kill() # you can terminate all the other instances
                sys.exit() # or your way, terminate this newer instance here

因为os.system(“ ps ax | grep sample_python.py”)返回0。这不是正确的。

看这个问题: 将os.system的输出分配给一个变量,并防止它在屏幕上显示

你必须写

os.popen('cat /etc/services').read() 

但是由于您的脚本已经启动,因此您总是会转到“失败”状态。 您必须计算返回的行数...

在这里作为单个实例的变体:

Python:程序的单个实例

我写了这样的剧本。 我创建了一个文件名开头的文件,并在末尾删除了文件。 这是守护程序脚本。 开始时,我检查了该文件是否存在。

不错的变体在这里确保Linux中应用程序的单个实例

import fcntl
pid_file = 'program.pid'
fp = open(pid_file, 'w')
try:
    fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
    # another instance is running
    sys.exit(1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM