在spyder ipython中启用subprocess.run的打印

时间:2018-02-13 14:20:08

标签: python subprocess python-3.6 spyder

我在Windows 10上运行spyder,当我尝试运行类似于以下的命令时:

cmd = 'python /path/to/program.py arg1 arg2'
subprocess.run(cmd,shell=True)

脚本正在按预期运行,但我希望通过spyder ipython控制台中的执行命令查看正在打印的内容。我知道程序正在按照其他方法(从shell运行程序)的方式将内容打印到屏幕上,因此我正在运行的脚本中没有错误。

如何启用子流程的打印?

1 个答案:

答案 0 :(得分:2)

输出来自名为stdout的流。要捕获它,您需要将其重定向到管道,然后在管道进程中终止管道。 subprocess.run(...)已内置支持处理此问题:

import subprocess
cmd = 'python /path/to/program.py arg1 arg2'.split()
proc = subprocess.run(cmd, stdout=subprocess.PIPE, universal_newlines=True)
print(proc.stdout)

可以看出,输出被捕获在CompletedProcess对象(proc) and then accessed as member data.中。另外,为了使输出成为文本(字符串)而不是bytearray,我已经传递了参数{{ 1}}。

但需要注意的是,universal_newlines=True在返回控制权之前会运行完成。因此,这不允许捕获输出“实时”,而是在整个过程完成之后。如果您想要实时捕获,则必须使用subprocess.run(...),然后使用subprocess.Popen(...)或其他一些通信方式来捕获子进程的输出。

我想提出的另一个评论是,不建议使用.communicate()。特别是在处理未知或不可信输入时。它将shell=True的解释留给shell,这可能导致各种安全漏洞和不良行为。相反,将cmd拆分为一个列表(例如我已经完成),然后将该列表传递给cmd并省略subprocess.run(...)