Python 的 subprocess 模块提供了与系统进程进行交互的能力,允许我们在 Python 中启动新进程并与其进行通信。当我们启动一个子进程时,有时候需要实时输出子进程的日志信息,这就需要用到 subprocess 模块中的 pipe 和实时输出函数(如: poll、communicate等)。
下面是实时输出子进程日志信息的完整攻略:
- 使用 subprocess.Popen 启动子进程。
import subprocess
proc = subprocess.Popen(['command', 'arg1', 'arg2'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- 在子进程执行过程中,使用 communicate() 函数等待子进程执行结束,并实时输出子进程的日志信息。另外,使用 poll() 函数判断子进程是否结束。
while True:
output = proc.stdout.readline()
if output == '' and proc.poll() is not None:
break
if output:
print(output.strip())
output = proc.stderr.readline()
if output == '' and proc.poll() is not None:
break
if output:
print(output.strip())
retval = proc.poll()
在实时输出日志的过程中,我们发现每条日志输出时都带有一个换行符号,这是因为 readline 函数会读取到换行符然后输出。
下面是一个简单的示例,该示例会启动一个子进程并调用它打印程序的版本信息。
import subprocess
proc = subprocess.Popen(['python', '-V'], stdout=subprocess.PIPE)
while True:
output = proc.stdout.readline()
if output == '' and proc.poll() is not None:
break
if output:
print(output.strip())
retval = proc.poll()
下面是另一个更完整的示例,该示例将在 Python 程序中启动一个 Shell 子进程并循环输出子进程的日志信息,直到子进程执行结束。
# -*- coding: utf-8 -*-
import subprocess
import sys
if len(sys.argv) < 2:
print('Usage: python run_subprocess.py <command>')
sys.exit(1)
try:
proc = subprocess.Popen(
sys.argv[1:],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
while True:
# Read stdout and stderr
output = proc.stdout.readline() + proc.stderr.readline()
if output == '' and proc.poll() is not None:
break
if output:
print(output.strip())
retval = proc.wait()
print('RETVAL:', retval)
except OSError as e:
# Handle OSError
pass
这个示例中,我们在命令行中运行了一个参数化的命令,并使用 subprocess.Popen 对其进行处理。将 stdout 和 stderr 设置为 subprocess.PIPE,表示我们要从子进程中获取输出。然后,我们开始循环,读取 stdout 和 stderr,直到子进程结束。最后,我们打印子进程的返回值。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python subprocess pipe 实时输出日志的操作 - Python技术站