[英]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。
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()
但是由于您的脚本已经启动,因此您总是会转到“失败”状态。 您必须计算返回的行数...
在这里作为单个实例的变体:
我写了这样的剧本。 我创建了一个文件名开头的文件,并在末尾删除了文件。 这是守护程序脚本。 开始时,我检查了该文件是否存在。
不错的变体在这里确保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.