【问题标题】:Start another process in background and capture output in Python在后台启动另一个进程并在 Python 中捕获输出
【发布时间】:2018-09-04 15:53:33
【问题描述】:

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

我尝试使用subprocess.Popen,我能够作为后台进程生成并在几秒钟后终止。但是 atlast 将 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

【问题讨论】:

  • 不要混用线程和fork linuxprogrammingblog.com/…
  • 没错。最初我使用的是无线程,后来为了解决该块问题,我尝试了线程。

标签: python python-2.7 stdout spawn


【解决方案1】:

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'

【讨论】:

  • 不工作。这也阻止了communicate 调用。
  • 正如你所指出的 shell=True 实际上是问题所在,总是更喜欢 shell=False,但是你的代码可以在我的 Linux 环境中运行
【解决方案2】:

删除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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 2016-02-21
    • 2021-05-06
    • 2012-05-12
    • 2020-03-24
    • 2017-09-17
    相关资源
    最近更新 更多