在后台启动另一个进程并在 Python 中捕获输出

Start another process in background and capture output in Python

在 python 中,我想启动另一个 python 脚本作为后台进程,几秒后我需要终止该生成的进程并将标准输出放入变量中。

我试过 subprocess.Popen,我能够作为后台进程产生并在几秒后终止。但最后在将 stdout 重定向到一个变量时它被阻止了。

有人可以建议我修复它吗?或者除了 subprocess.Popen 之外还有其他模块可用于执行此操作吗?

g_flag = 0
class StartChecking(Thread):
    def __init__(self):
        Thread.__init__(self)
    def run(self):
        global g_flag
        print 'Starting thread'
        proc = subprocess.Popen(["./cmd.py"], stdout=subprocess.PIPE, shell=True)
        pid = proc.pid
        print 'Sniff started ' + str(pid)
        if (pid != 0) and (pid != 1):
            while g_flag == 0:
                sleep(0.1)
            os.kill(pid, signal.SIGTERM)
            print 'Killed ' + str(pid)
        (out, err) = proc.communicate() # Currently its blocking here
        print out


th = StartChecking()
th.start()
#Do something else
sleep(5)
g_flag = 1
th.join()
print 'thread joined'

输出是

Starting thread
Sniff started 24294
Killed 24294

注意:在 ubuntu 16.04 中使用 Python 2.7.12

Here is a good explaination of shell=True

将 shell 参数设置为真值会导致子进程生成一个中间 shell 进程,并告诉它 运行 命令

始终使用=shell=False,但是您的代码在我的 linux 环境中工作,如下所示,为简单起见,我使用 shell 文件作为 运行 的命令] :

import os,signal
import time
import subprocess
from threading import Thread

g_flag = 0
class StartChecking(Thread):
    def __init__(self):
        Thread.__init__(self)
    def run(self):
        global g_flag
        print 'Starting thread'
        proc = subprocess.Popen(["./a.sh"], stdout=subprocess.PIPE, shell=True)
        pid = proc.pid
        print 'Sniff started ' + str(pid)
        if (pid != 0) and (pid != 1):
            while g_flag == 0:
                time.sleep(0.1)
            os.kill(pid, signal.SIGTERM)
            print 'Killed ' + str(pid)
        (out, err) = proc.communicate() # Currently its blocking here
        print out


th = StartChecking()
th.start()
#Do something else
time.sleep(5)
g_flag = 1
th.join()
print 'thread joined'

删除 shell=True 后它开始工作。并在没有线程的情况下重组了代码。如果我添加 shell=True 然后它再次开始阻塞 communicate 调用。

proc = subprocess.Popen(["./cmd.py"], stdout=subprocess.PIPE)
#Do something else
sleep(2)
os.system('kill -15 ' + str(proc.pid))
print 'Killed ' + str(proc.pid)
print 'cmd out: ' + proc.communicate()[0]
print 'finished'