在终端中显示 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 中的结果相当满意。 (输出感觉相当自然。)
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 中的结果相当满意。 (输出感觉相当自然。)