读取子进程标准输出,同时将其保存在缓冲区中
Read subprocess stdout while maintaining it in the buffer
是否可以读取子进程的 stdout
但在程序结束时仍然保持整个 process.communicate()
?
例如,我有一个 python 脚本,它在 Popen
子进程中启动一个 c# 应用程序,并检查它实时生成的日志文件以确定它所处的状态,但某些错误不会被转储在日志中并在 stdout
中,某些错误会导致进程挂起。我希望能够检测到该输出,并且在那些情况下能够终止进程。
这在执行 process.stdout.readline()
时很容易,但在程序结束时我失去了以其本机格式转储整个 stdout 的能力,因为缓冲区在读取后被刷新。是否可以维护该缓冲区?
或者至少将读取的行以其本机格式保存在变量中?
您可以逐行读取标准输出,对其进行处理并将其保存到列表或缓冲区中,稍后可以使用缓冲区。在此示例中,处理只是 print
,但您可以根据需要进行更改。我还假设你只是想在后台收集 stderr,所以创建了一个单独的线程。
import subprocess as subp
import threading
import io
def _pipe_read_thread(stream, output):
output.write(stream.read())
stream.close()
def proc_runner(cmd):
stdout_lines = []
stdout_buf = io.BytesIO()
stderr_buf = io.BytesIO()
p = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE)
stderr_t = threading.Thread(target=_pipe_read_thread,
args=(p.stderr, stderr_buf))
stderr_t.start()
for line in p.stdout:
print(line)
stdout_buf.write(line)
returncode = p.wait()
stderr_t.join()
stdout_buf. seek(0)
stderr_buf.seek(0)
return returncode, stdout_buf, stderr_buf
returncode, stdout, stderr = proc_runner(['ls', '-a'])
print('=============================')
print(stdout.read())
print('=============================')
print(stderr.read())
是否可以读取子进程的 stdout
但在程序结束时仍然保持整个 process.communicate()
?
例如,我有一个 python 脚本,它在 Popen
子进程中启动一个 c# 应用程序,并检查它实时生成的日志文件以确定它所处的状态,但某些错误不会被转储在日志中并在 stdout
中,某些错误会导致进程挂起。我希望能够检测到该输出,并且在那些情况下能够终止进程。
这在执行 process.stdout.readline()
时很容易,但在程序结束时我失去了以其本机格式转储整个 stdout 的能力,因为缓冲区在读取后被刷新。是否可以维护该缓冲区?
或者至少将读取的行以其本机格式保存在变量中?
您可以逐行读取标准输出,对其进行处理并将其保存到列表或缓冲区中,稍后可以使用缓冲区。在此示例中,处理只是 print
,但您可以根据需要进行更改。我还假设你只是想在后台收集 stderr,所以创建了一个单独的线程。
import subprocess as subp
import threading
import io
def _pipe_read_thread(stream, output):
output.write(stream.read())
stream.close()
def proc_runner(cmd):
stdout_lines = []
stdout_buf = io.BytesIO()
stderr_buf = io.BytesIO()
p = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE)
stderr_t = threading.Thread(target=_pipe_read_thread,
args=(p.stderr, stderr_buf))
stderr_t.start()
for line in p.stdout:
print(line)
stdout_buf.write(line)
returncode = p.wait()
stderr_t.join()
stdout_buf. seek(0)
stderr_buf.seek(0)
return returncode, stdout_buf, stderr_buf
returncode, stdout, stderr = proc_runner(['ls', '-a'])
print('=============================')
print(stdout.read())
print('=============================')
print(stderr.read())