【问题标题】:Process execution check and getting PID in PythonPython中的进程执行检查和获取PID
【发布时间】:2014-06-23 16:35:05
【问题描述】:

我需要在后台运行一个 bash 命令,但稍后需要 kill(os.kill()) 它。我还想确保命令运行我有这个以确保命令运行。

if subprocess.Popen("tcpdump -i eth0 -XX -w /tmp/tmp.cap &", shell=True).wait() == 0:

我不确定如何更改此设置,因此我可以使用 Popen.pid 获取 pid,同时仍然能够检查执行是否成功。 任何帮助,将不胜感激。 谢谢。

【问题讨论】:

  • 你可以使用变量p = Popen(...)p.kill()——杀死,returncode = p.wait()——等待完成。顺便说一句,这里不需要shell=True:在最后删除shell=True& 并使用p = Popen(shlex.split(cmd))
  • 是的,我不确定我是否需要 shell=True 或 & 但它适用于他们,我会尝试你的建议,谢谢你的时间。

标签: python if-statement subprocess popen pid


【解决方案1】:

要启动一个子进程,等待一段时间并终止它,并检查它的退出状态是否为零:

import shlex
from subprocess import Popen
from threading import Timer

def kill(process):
    try:
        process.kill()
    except OSError: 
        pass # ignore

p = Popen(shlex.split("tcpdump -i eth0 -XX -w /tmp/tmp.cat"))
t = Timer(10, kill, [p]) # run kill in 10 seconds
t.start()
returncode = p.wait()
t.cancel()
if returncode != 0:
   # ...

或者您可以自己实现超时:

import shlex
from subprocess import Popen
from time import sleep, time as timer # use time.monotonic instead

p = Popen(shlex.split("tcpdump -i eth0 -XX -w /tmp/tmp.cat"))

deadline = timer() + 10 # kill in 10 seconds if not complete
while timer() < deadline:
    if p.poll() is not None: # process has finished
        break 
    sleep(1) # sleep a second
else: # timeout happened
    try:
        p.kill()
    except OSError:
        pass

if p.wait() != 0:
   # ...

假设sleep 使用与timer 相似的时钟。

threading.Timer 变体允许您的代码在子进程退出后立即继续。

【讨论】:

  • Popen.wait() 不允许进程按照 OP 的要求“在后台运行”。
  • @Graham: .wait() 仅在进程 已经 完成(在第二个示例中)或被杀死后调用。在这两种情况下,该过程在 10 秒后都无法生存。 “背景”是来自外壳的术语。这里没有贝壳。 Popen 在“后台”运行所有进程,除非您的意思是要创建一个 unix 守护进程(OP 不太可能需要它)
【解决方案2】:

使用Popen.poll() 方法。您也可以获取Popen.returncode 来确定流程是否成功完成。

import subprocess

tasks = [subprocess.Popen('ping www.stackoverflow.com -n 5 && exit 0', shell=True),
         subprocess.Popen('ping www.stackoverflow.com -n 5 && exit 1', shell=True)]

for task in tasks:
    while task.poll() is None:
        # the task has not finished
        pass

    print task
    print task.pid
    print task.returncode

【讨论】:

  • OP 启动 single 进程。 task.returncode 检查是多余的。 not task.poll() 错误:应该是 task.poll() is None -- 进程仍在运行。一般来说,应该避免忙循环(您可以在检查之间暂停)。
  • @J.F.塞巴斯蒂安,我知道 OP 启动了一个进程,而不是 ping... OP 想知道进程成功终止,并且两个示例进程以不同的退出代码终止以演示该功能。
  • 感谢您的回复,如果我的问题误导了您,我很抱歉,我想检查进程是否成功执行,但进程应该一直在后台运行,直到被杀死。就像没有安装 TCPDump 一样,它将无法运行,我想知道这一点。感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
相关资源
最近更新 更多