首页 > 解决方案 > Jupyter notebook 中 shell 命令的实时输出

问题描述

我告诉 jupyter 执行一个 python 脚本:

!python build_database.py

从终端执行时,python 脚本会打印执行过程中的进度。但是,在 jupyter notebook 中,我在执行之后将所有输出打印为字符串列表。有没有办法实时查看输出?

标签: pythonjupyter-notebook

解决方案


看起来不可能开箱即用。shell 命令的输出处理深藏在 ipython 内部。

我推荐的解决方案之一是根据下面的代码创建自定义魔术方法。

检查这个答案

基于它,我创建了一个可以使用的简单魔术方法:

from subprocess import Popen, PIPE, STDOUT

from IPython.core.magic import register_line_magic


@register_line_magic
def runrealcmd(command):
    process = Popen(command, stdout=PIPE, shell=True, stderr=STDOUT, bufsize=1, close_fds=True)
    for line in iter(process.stdout.readline, b''):
        print(line.rstrip().decode('utf-8'))
    process.stdout.close()
    process.wait()

或者Popen可以用作上下文管理器。因此,代码将更具可读性和可靠性。查看文档

通过 with 语句支持 Popen 对象作为上下文管理器:退出时,标准文件描述符被关闭,并等待进程。

from subprocess import Popen, PIPE, STDOUT

from IPython.core.magic import register_line_magic


@register_line_magic
def runrealcmd(command):
    with Popen(
        command, stdout=PIPE, shell=True, stderr=STDOUT, bufsize=1, close_fds=True
    ) as process:
        for line in iter(process.stdout.readline, b""):
            print(line.rstrip().decode("utf-8"))

用法:

%runrealcmd ping -c10 www.google.com

上面的代码可能可以写得更好,但根据您的需要,它应该非常好。


推荐阅读