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)
它不会杀死旧进程并且现在运行多次.
使用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)
我个人在解决此类问题时的偏好是让脚本在一个独特的、众所周知的位置创建一个 pidfile,它将在其中放置自己的 pid。这使得确定可能已经在运行的进程的 pid 更加可靠。
在创建 pidfile 并可靠地写入它自己的 pid 时,您仍然必须考虑竞争条件。通常重新检查文件内容并在检测到不匹配时自杀就足以确保最多存在一个正在运行的进程实例,而不管进程实际如何命名。
我当前的解决方案看起来像这样(在 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 字符串不同,这也应该有效。脚本的位置也不重要