Python中进程执行检查和获取PID

1 投票
2 回答
1528 浏览
提问于 2025-04-18 05:36

我需要在后台运行一个bash命令,但之后还需要把它杀掉(用os.kill())。我还想确保这个命令能够成功运行,所以我有一些代码来确保它能执行。

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

我不太确定该怎么改动这段代码,以便我可以用Popen.pid来获取进程的ID,同时又能检查这个命令是否成功执行。希望能得到一些帮助。谢谢。

2 个回答

0

使用 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
2

要启动一个子进程,等一段时间后把它杀掉,并检查它的退出状态是否为零:

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:
   # ...

这里假设 sleeptimer 使用的是类似的时钟。

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

撰写回答