如何隐藏子进程的输出并继续执行脚本?

Posted

技术标签:

【中文标题】如何隐藏子进程的输出并继续执行脚本?【英文标题】:How do I hide the output from a subprocess and continue the script execution? 【发布时间】:2016-10-28 02:45:39 【问题描述】:

如何启动子进程或运行具有连续输出流的 python 文件并同时运行脚本的其余部分?

这里是一些示例代码:

import subprocess

p = subprocess.Popen('python myScript.py', shell=True, stdout=subprocess.PIPE)

#this program will have a stream of output and is designed to run for
#long periods of time

print 'the program is still running!'

doMoreStuff()

【问题讨论】:

这个脚本有问题吗?看起来它可以满足您的要求。 问题是脚本有我无法控制的输出。一个更好的例子是执行嗅探器或具有恒定输出流的东西的命令。无论出于何种原因,该程序都在吐出我不需要的信息。我需要知道如何运行该命令并忽略输出,同时返回脚本的其余部分而不输出随机垃圾。 您没有看到stdout 数据,所以您看到的是stderr。一般来说,您希望数据发生什么变化?倾倒它?将其写入文件?把它留在记忆中? 【参考方案1】:

在您的示例代码中调用 subprocess.Popen() 后,主进程将立即进入 print() 语句,然后执行 doMoreStuff(),同时运行脚本的其余部分。

【讨论】:

我的示例代码是一个示例,我正在尝试执行一个程序,该程序以破坏我的程序的方式输出数据。 所以您想忽略 myScript.py 的输出?通过在 Linux 中将 subprocess.Popen('python myScript.py', shell=True, stdout=subprocess.PIPE) 更改为 subprocess.Popen('python myScript.py > /dev/null 2>&1', shell=True, stdout=subprocess.PIPE) 或在 Windows 中将 subprocess.Popen('python myScript.py > NUL', shell=True)【参考方案2】:

如果你想让程序静默,你需要捕获stderr以及stdout。两个选择是stderr=subprocess.STDOUT,这意味着您要在标准输出管道上交错标准输出和错误。或stderr=subprocess.PIPE 以保持标准错误不同。

但是你还有第二个问题。因为您没有阅读stdout,所以如果程序输出足够的数据来填充管道,它将挂起。还有一个潜在的第三个问题——在某个地方你需要调用p.wait(),这样你就不会遇到僵尸进程。

您可以将它们发送到文件中:

proc = subprocess.Popen('python myScript.py', shell=True, 
    stdout=open('stdout.txt', 'wb'), stderr=open('stderr.txt', 'wb'))

或者让后台线程完成工作:

def out_err_thread(out_err_list, proc):
    out, err = proc.communicate()

proc = subprocess.Popen('python myScript.py', shell=True, 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out_err = []
_t = threading.Thread(target=out_err_thread, args=(out_err, proc))
_t.start()

或者将它们发送到比特桶

proc = subprocess.Popen('python myScript.py', shell=True, 
    stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)

【讨论】:

以上是关于如何隐藏子进程的输出并继续执行脚本?的主要内容,如果未能解决你的问题,请参考以下文章

Python windows脚本子进程在脚本结束后继续输出

linux 中如何执行脚本?

linux 中如何执行脚本?

C中进程间通信中的数据流控制[关闭]

子进程 readline 挂起等待 EOF

Linux写一个shell脚本,要实现在键盘输入一个进程号,输出这个进程号的子进程pid,怎么写?