来自Jupyter笔记本中的Python子进程的实时stdout输出

Joh*_*ter 16 python subprocess stdout ipython jupyter

我正在使用子进程从Python(3.5.2)脚本运行命令行程序,我在Jupyter笔记本中运行该脚本.子进程需要很长时间才能运行,因此我希望它的stdout能够在Jupyter笔记本中实时打印到屏幕上.

我可以在从终端运行的普通Python脚本中做到这一点没问题.我这样做使用:

def run_command(cmd):
from subprocess import Popen, PIPE
import shlex

with Popen(shlex.split(cmd), stdout=PIPE, bufsize=1, universal_newlines=True) as p:
    for line in p.stdout:
        print(line, end='')
    exit_code = p.poll()
return exit_code
Run Code Online (Sandbox Code Playgroud)

但是,当我在Jupyter笔记本中运行脚本时,它不会将stdout实时打印到屏幕上.相反,它会在子进程运行完毕后打印所有内容.

有没有人对如何解决这个问题有任何想法?

非常感谢,约翰尼

cdl*_*ard 12

ipython笔记本拥有自己对运行shell命令支持.如果您不需要使用子进程捕获,则可以执行此操作

cmd = 'ls -l'
!{cmd}
Run Code Online (Sandbox Code Playgroud)

用!执行的命令输出!通过笔记本自动传送.


Flu*_*mur 4

如果您设置stdout = None(这是默认值,因此您可以stdout完全省略该参数),那么您的进程应将其输出写入运行 IPython 笔记本服务器的终端。

发生这种情况是因为子进程的默认行为是从父文件处理程序继承(请参阅文档)。

你的代码看起来像这样:

from subprocess import Popen, PIPE
import shlex

def run_command(cmd):
    p = Popen(shlex.split(cmd), bufsize=1, universal_newlines=True)
    return p.poll()
Run Code Online (Sandbox Code Playgroud)

这不会打印到浏览器中的笔记本,但至少您可以在其他代码运行时异步查看子进程的输出。

希望这可以帮助。