在终端中显示 subprocess.Popen 的输出,就好像 运行

show output from subprocess.Popen as if run in terminal

  subprocess.Popen('dstat --output stats.csv', shell=True, stdout=subprocess.PIPE).stdout.read()

我正在使用 ipython,当我 运行 上面的命令没有打印在控制台上。有没有办法在控制台 window 中看到与我直接在 linux 终端中 运行 命令看到的相同的输出?

您正在将 dstat 命令的 CSV 输出写入 stats.csv 文件。

应该从 stats.csv 文件而不是标准输出中读取输出,除非您删除命令中传递的 --output 选项。

写完下面的答案后,我想起有一种方法可以像shell一样突破IPython和运行。具体来说,如果您的行以感叹号 (!) 开头,IPython 将像在命令行上一样执行命令。

例如,如果我 运行 !dstat --output stats.csv,我得到以下内容:

我仍然保留下面基于自定义代码的方法,因为编写起来很有趣,但显然,内置解决方案(即,在命令前加上 !)可能会更好你的用法。


低于此点的自定义解决方案

这个怎么样?

"""Simulate command-line execution."""
import os
import sys
import subprocess
import signal
from time import sleep


def local_command(command):
    """Simulate command execution as if on command-line."""
    env_to_pass = dict(os.environ)
    kwargs_for_popen = {
        'shell': True,
        'bufsize': 1,
        'stdin': sys.stdin.fileno(),
        'stdout': sys.stdout.fileno(),
        'stderr': sys.stderr.fileno(),
        'env': env_to_pass
    }
    # Determine which keyword we should use for putting the process I/O into
    # text-only mode.
    if sys.hexversion >= 0x3070000:
        # "text" was added as a keyword argument alias for "universal_newlines"
        # in Python 3.7, and "universal_newlines" is provided still only for
        # backwards compatibility. Let's do this right if we're going to do it.
        kwargs_for_popen['text'] = True
    else:
        # For systems with python before 3.7, use "universal_newlines"
        kwargs_for_popen['universal_newlines'] = True

    sp = subprocess.Popen(command, **kwargs_for_popen)
    while True:
        try:
            while sp.poll() is None:
                sleep(0.02)
        except KeyboardInterrupt:
            sp.send_signal(signal.SIGINT)
            sleep(0.02)
        if sp.poll() is not None:
            # Process has terminated.
            # Exit event loop.
            break
    # end while

    sp_stdout_data, sp_stderr_data = sp.communicate()
    print(sp_stdout_data)
    return sp.returncode

来自 IPython 运行ning Python 3.7.3 Ubuntu 的输出:

代码不是特别漂亮,但您可以轻松地将其放入自己的模块中,然后调用该函数。我对 IPython 中的结果相当满意。 (输出感觉相当自然。)