• <legend id='qg5B7'><style id='qg5B7'><dir id='qg5B7'><q id='qg5B7'></q></dir></style></legend>
      <i id='qg5B7'><tr id='qg5B7'><dt id='qg5B7'><q id='qg5B7'><span id='qg5B7'><b id='qg5B7'><form id='qg5B7'><ins id='qg5B7'></ins><ul id='qg5B7'></ul><sub id='qg5B7'></sub></form><legend id='qg5B7'></legend><bdo id='qg5B7'><pre id='qg5B7'><center id='qg5B7'></center></pre></bdo></b><th id='qg5B7'></th></span></q></dt></tr></i><div id='qg5B7'><tfoot id='qg5B7'></tfoot><dl id='qg5B7'><fieldset id='qg5B7'></fieldset></dl></div>
      <tfoot id='qg5B7'></tfoot>
      • <bdo id='qg5B7'></bdo><ul id='qg5B7'></ul>

        <small id='qg5B7'></small><noframes id='qg5B7'>

        将子进程输出显示到标准输出并重定向它

        时间:2023-07-22
      1. <i id='WmUaA'><tr id='WmUaA'><dt id='WmUaA'><q id='WmUaA'><span id='WmUaA'><b id='WmUaA'><form id='WmUaA'><ins id='WmUaA'></ins><ul id='WmUaA'></ul><sub id='WmUaA'></sub></form><legend id='WmUaA'></legend><bdo id='WmUaA'><pre id='WmUaA'><center id='WmUaA'></center></pre></bdo></b><th id='WmUaA'></th></span></q></dt></tr></i><div id='WmUaA'><tfoot id='WmUaA'></tfoot><dl id='WmUaA'><fieldset id='WmUaA'></fieldset></dl></div>

        <tfoot id='WmUaA'></tfoot>

            <small id='WmUaA'></small><noframes id='WmUaA'>

              <bdo id='WmUaA'></bdo><ul id='WmUaA'></ul>

            • <legend id='WmUaA'><style id='WmUaA'><dir id='WmUaA'><q id='WmUaA'></q></dir></style></legend>

                    <tbody id='WmUaA'></tbody>
                  本文介绍了将子进程输出显示到标准输出并重定向它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在通过 Python 的子进程模块运行脚本.目前我使用:

                  I'm running a script via Python's subprocess module. Currently I use:

                  p = subprocess.Popen('/path/to/script', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                  result = p.communicate()
                  

                  然后我将结果打印到标准输出.这一切都很好,但是由于脚本需要很长时间才能完成,所以我也希望从脚本实时输出到标准输出.我管道输出的原因是因为我想解析它.

                  I then print the result to the stdout. This is all fine but as the script takes a long time to complete, I wanted real time output from the script to stdout as well. The reason I pipe the output is because I want to parse it.

                  推荐答案

                  将子进程的标准输出保存到变量中以供进一步处理和 在子进程到达时运行时显示它:

                  To save subprocess' stdout to a variable for further processing and to display it while the child process is running as it arrives:

                  #!/usr/bin/env python3
                  from io import StringIO
                  from subprocess import Popen, PIPE
                  
                  with Popen('/path/to/script', stdout=PIPE, bufsize=1,
                             universal_newlines=True) as p, StringIO() as buf:
                      for line in p.stdout:
                          print(line, end='')
                          buf.write(line)
                      output = buf.getvalue()
                  rc = p.returncode
                  

                  保存子进程的 stdout 和 stderr 更复杂,因为您应该同时使用两个流以避免死锁:

                  To save both subprocess's stdout and stderr is more complex because you should consume both streams concurrently to avoid a deadlock:

                  stdout_buf, stderr_buf = StringIO(), StringIO()
                  rc =  teed_call('/path/to/script', stdout=stdout_buf, stderr=stderr_buf,
                                  universal_newlines=True)
                  output = stdout_buf.getvalue()
                  ...
                  

                  teed_call() 在这里定义.

                  where teed_call() is define here.

                  更新:这里是一个更简单的asyncio版本.

                  旧版本:

                  这是一个基于 child_process 的单线程解决方案.py 示例来自 tulip:

                  Here's a single-threaded solution based on child_process.py example from tulip:

                  import asyncio
                  import sys
                  from asyncio.subprocess import PIPE
                  
                  @asyncio.coroutine
                  def read_and_display(*cmd):
                      """Read cmd's stdout, stderr while displaying them as they arrive."""
                      # start process
                      process = yield from asyncio.create_subprocess_exec(*cmd,
                              stdout=PIPE, stderr=PIPE)
                  
                      # read child's stdout/stderr concurrently
                      stdout, stderr = [], [] # stderr, stdout buffers
                      tasks = {
                          asyncio.Task(process.stdout.readline()): (
                              stdout, process.stdout, sys.stdout.buffer),
                          asyncio.Task(process.stderr.readline()): (
                              stderr, process.stderr, sys.stderr.buffer)}
                      while tasks:
                          done, pending = yield from asyncio.wait(tasks,
                                  return_when=asyncio.FIRST_COMPLETED)
                          assert done
                          for future in done:
                              buf, stream, display = tasks.pop(future)
                              line = future.result()
                              if line: # not EOF
                                  buf.append(line)    # save for later
                                  display.write(line) # display in terminal
                                  # schedule to read the next line
                                  tasks[asyncio.Task(stream.readline())] = buf, stream, display
                  
                      # wait for the process to exit
                      rc = yield from process.wait()
                      return rc, b''.join(stdout), b''.join(stderr)
                  

                  脚本运行 '/path/to/script 命令并同时逐行读取其标准输出和标准错误.这些行相应地打印到父级的 stdout/stderr 并保存为字节串以供将来处理.要运行 read_and_display() 协程,我们需要一个事件循环:

                  The script runs '/path/to/script command and reads line by line both its stdout&stderr concurrently. The lines are printed to parent's stdout/stderr correspondingly and saved as bytestrings for future processing. To run the read_and_display() coroutine, we need an event loop:

                  import os
                  
                  if os.name == 'nt':
                      loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows
                      asyncio.set_event_loop(loop)
                  else:
                      loop = asyncio.get_event_loop()
                  try:
                      rc, *output = loop.run_until_complete(read_and_display("/path/to/script"))
                      if rc:
                          sys.exit("child failed with '{}' exit code".format(rc))
                  finally:
                      loop.close()
                  

                  这篇关于将子进程输出显示到标准输出并重定向它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:Python 弹出命令.等到命令完成 下一篇:从python运行程序,并在脚本被杀死后继续运行

                  相关文章

                    <legend id='jhHaF'><style id='jhHaF'><dir id='jhHaF'><q id='jhHaF'></q></dir></style></legend>
                  1. <tfoot id='jhHaF'></tfoot>
                    • <bdo id='jhHaF'></bdo><ul id='jhHaF'></ul>
                  2. <i id='jhHaF'><tr id='jhHaF'><dt id='jhHaF'><q id='jhHaF'><span id='jhHaF'><b id='jhHaF'><form id='jhHaF'><ins id='jhHaF'></ins><ul id='jhHaF'></ul><sub id='jhHaF'></sub></form><legend id='jhHaF'></legend><bdo id='jhHaF'><pre id='jhHaF'><center id='jhHaF'></center></pre></bdo></b><th id='jhHaF'></th></span></q></dt></tr></i><div id='jhHaF'><tfoot id='jhHaF'></tfoot><dl id='jhHaF'><fieldset id='jhHaF'></fieldset></dl></div>

                    <small id='jhHaF'></small><noframes id='jhHaF'>