检查Python脚本是否已在运行

Mar*_*tin 7 python linux kill process

我希望我的Python脚本检查,如果它已经运行,如果是,则杀死旧进程.我试过这个,但它确实不起作用......

import os
import subprocess
import signal

process_name = "python " + os.path.abspath(__file__)
proc = subprocess.Popen(["pgrep", process_name], stdout=subprocess.PIPE)

# Kill process.
for pid in proc.stdout:
    os.kill(int(pid), signal.SIGTERM)
    # Check if the process that we killed is alive.
    try:
        os.kill(int(pid), 0)
        raise Exception("""wasn't able to kill the process
                          HINT:use signal.SIGKILL or signal.SIGABORT""")
    except OSError as ex:
        continue
Run Code Online (Sandbox Code Playgroud)

它不会杀死旧进程并且现在运行多次.

Dan*_*scu 5

使用pgrep基于您的方法确定 python 脚本是否正在运行是不可靠的。例如:

> ps -ef | grep 'python sleep.py'
userid  21107  2069  0 12:51 pts/3    00:00:00 python sleep.py
userid  21292  2069  0 13:08 pts/3    00:00:00 grep python sleep.py
> pgrep 'python sleep.py'
> 
Run Code Online (Sandbox Code Playgroud)

通过名称识别正在运行的 python 脚本的其他困难:

  • 实际的python字符串可能会有所不同,具体取决于脚本的执行方式,例如它可能如下所示:

/usr/bin/python2.7 sleep.py

  • os.path.abspath(__file__)如果脚本是指向实际文件的符号链接并且可以从两个位置执行,则使用该方法在进程名称中定位脚本可能会失败

例子:

> cat abs_path.py
import os
print os.path.abspath(__file__)
> ls -l abs_path.py 
lrwxrwxrwx 1 userid at 15 Apr 22 13:22 abs_path.py -> bin/abs_path.py
> python abs_path.py
/home/userid/abs_path.py
> python bin/abs_path.py
/home/userid/bin/abs_path.py
Run Code Online (Sandbox Code Playgroud)
  • 进程(包括来自 python 脚本的进程)实际上可以在执行期间更改它们的名称(可能不是在您的脚本的情况下,是的)

我个人在解决此类问题时的偏好是让脚本在一个独特的、众所周知的位置创建一个 pidfile,它将在其中放置自己的 pid。这使得确定可能已经在运行的进程的 pid 更加可靠。

在创建 pidfile 并可靠地写入它自己的 pid 时,您仍然必须考虑竞争条件。通常重新检查文件内容并在检测到不匹配时自杀就足以确保最多存在一个正在运行的进程实例,而不管进程实际如何命名。


Mic*_*nen 5

我当前的解决方案看起来像这样(在 OSX 上)。我将 pgrep 与 regexp 结合使用

import subprocess

cmd = ['pgrep -f .*python.*testing03.py']
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, 
stderr=subprocess.PIPE)
my_pid, err = process.communicate()

if len(my_pid.splitlines()) >0:
   print("Running")
   exit()
else:
  print("Not Running")
Run Code Online (Sandbox Code Playgroud)

据我测试,即使 python 字符串不同,这也应该有效。脚本的位置也不重要