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

      1. <tfoot id='GKr1K'></tfoot>
        <legend id='GKr1K'><style id='GKr1K'><dir id='GKr1K'><q id='GKr1K'></q></dir></style></legend>

      2. <i id='GKr1K'><tr id='GKr1K'><dt id='GKr1K'><q id='GKr1K'><span id='GKr1K'><b id='GKr1K'><form id='GKr1K'><ins id='GKr1K'></ins><ul id='GKr1K'></ul><sub id='GKr1K'></sub></form><legend id='GKr1K'></legend><bdo id='GKr1K'><pre id='GKr1K'><center id='GKr1K'></center></pre></bdo></b><th id='GKr1K'></th></span></q></dt></tr></i><div id='GKr1K'><tfoot id='GKr1K'></tfoot><dl id='GKr1K'><fieldset id='GKr1K'></fieldset></dl></div>
          <bdo id='GKr1K'></bdo><ul id='GKr1K'></ul>
      3. 如何打印和显示子进程 stdout 和 stderr 输出而不失真?

        How can I print and display subprocess stdout and stderr output without distortion?(如何打印和显示子进程 stdout 和 stderr 输出而不失真?)
          <tfoot id='q8SNX'></tfoot>

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

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

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

              <tbody id='q8SNX'></tbody>

                  <bdo id='q8SNX'></bdo><ul id='q8SNX'></ul>
                  本文介绍了如何打印和显示子进程 stdout 和 stderr 输出而不失真?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  也许有人在外面可以帮助我解决这个问题.(我在 SO 上看到了许多与此类似的问题,但没有一个同时处理标准输出和标准错误或处理与我非常相似的情况,因此提出了这个新问题.)

                  Maybe there's someone out in the ether that can help me with this one. (I have seen a number of similar questions to this on SO, but none deal with both standard out and standard error or deal with a situation quite like mine, hence this new question.)

                  我有一个 python 函数,它打开一个子进程,等待它完成,然后输出返回码,以及标准输出和标准错误管道的内容.在进程运行时,我还想在填充两个管道时显示它们的输出.我的第一次尝试结果如下:

                  I have a python function that opens a subprocess, waits for it to complete, then outputs the return code, as well as the contents of the standard out and standard error pipes. While the process is running, I'd like to also display the output of both pipes as they are populated. My first attempt has resulted in something like this:

                  process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                  
                  stdout = str()
                  stderr = str()
                  returnCode = None
                  while True:
                      # collect return code and pipe info
                      stdoutPiece = process.stdout.read()
                      stdout = stdout + stdoutPiece
                      stderrPiece = process.stderr.read()
                      stderr = stderr + stderrPiece
                      returnCode = process.poll()
                  
                      # check for the end of pipes and return code
                      if stdoutPiece == '' and stderrPiece == '' and returnCode != None:
                          return returnCode, stdout, stderr
                  
                      if stdoutPiece != '': print(stdoutPiece)
                      if stderrPiece != '': print(stderrPiece)
                  

                  这有几个问题.因为 read() 一直读取到 EOF,所以 while 循环的第一行在子进程关闭管道之前不会返回.

                  There's a couple problems with this though. Because read() reads until an EOF, the first line of the while loop will not return until the subprocess closes the pipe.

                  我可以将 read() 替换为 read(int) 但打印输出失真,在读取字符的末尾被切断.我可以用 readline() 作为替代品,但是当同时出现许多输出和错误时,打印输出会失真.

                  I could replace the read() in favor of read(int) but the printed output is distorted, cut off at the end of the read characters. I could readline() as a replacement, but the printed output is distorted with alternating lines of output and errors when there are many of both that occur at the same time.

                  也许有一个我不知道的 read-until-end-of-buffer() 变体?还是可以实现?

                  Perhaps there's a read-until-end-of-buffer() variant that I'm not aware of? Or maybe it can be implemented?

                  也许最好按照 sys.stdout 包装器">回答另一个帖子?然而,我只想在这个函数中使用包装器.

                  Maybe it's best to implement a sys.stdout wrapper as suggested in this answer to another post? I would only want to use the wrapper in this function, however.

                  社区还有其他想法吗?

                  感谢您的帮助!:)

                  编辑:该解决方案确实应该是跨平台的,但如果您有不跨平台的想法,请将它们分享出去以保持头脑风暴的进行.

                  EDIT: The solution really should be cross-platform, but if you have ideas that aren't, please share them away to keep the brainstorming going.

                  对于我的另一个 python 子进程头抓手,看看我的另一个问题 在计时中考虑子进程开销.

                  For another one of my python subprocess head scratchers, take a look at another of my questions on accounting for subprocess overhead in timing.

                  推荐答案

                  使用 fcntl.fcntl,并使用 select.select 等待数据在任一管道中可用.例如:

                  Make the pipes non-blocking by using fcntl.fcntl, and use select.select to wait for data to become available in either pipe. For example:

                  # Helper function to add the O_NONBLOCK flag to a file descriptor
                  def make_async(fd):
                      fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
                  
                  # Helper function to read some data from a file descriptor, ignoring EAGAIN errors
                  def read_async(fd):
                      try:
                          return fd.read()
                      except IOError, e:
                          if e.errno != errno.EAGAIN:
                              raise e
                          else:
                              return ''
                  
                  process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                  make_async(process.stdout)
                  make_async(process.stderr)
                  
                  stdout = str()
                  stderr = str()
                  returnCode = None
                  
                  while True:
                      # Wait for data to become available 
                      select.select([process.stdout, process.stderr], [], [])
                  
                      # Try reading some data from each
                      stdoutPiece = read_async(process.stdout)
                      stderrPiece = read_async(process.stderr)
                  
                      if stdoutPiece:
                          print stdoutPiece,
                      if stderrPiece:
                          print stderrPiece,
                  
                      stdout += stdoutPiece
                      stderr += stderrPiece
                      returnCode = process.poll()
                  
                      if returnCode != None:
                          return (returnCode, stdout, stderr)
                  

                  请注意,fcntl 仅适用于类 Unix 平台,包括 Cygwin.

                  Note that fcntl is only available on Unix-like platforms, including Cygwin.

                  如果您需要它在没有 Cygwin 的情况下在 Windows 上工作,这是可行的,但要困难得多.您必须:

                  If you need it to work on Windows without Cygwin, it's doable, but it's much, much tougher. You'll have to:

                  • 使用 pywin32 库调用本机 Win32 API
                  • 使用 SetNamedPipeHandleStatePIPE_NOWAIT 使 stdout 和 stderr 管道非阻塞
                  • 使用 WaitForMultipleObjects 而不是 select 等待数据可用
                  • 使用 ReadFile 读取数据
                  • Use the pywin32 library to call through to the native Win32 API
                  • Use SetNamedPipeHandleState with PIPE_NOWAIT to make the stdout and stderr pipes non-blocking
                  • Use WaitForMultipleObjects instead of select to wait for data to become available
                  • Use ReadFile to read the data

                  这篇关于如何打印和显示子进程 stdout 和 stderr 输出而不失真?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Pythonic and efficient way of finding adjacent cells in grid(在网格中查找相邻单元格的 Pythonic 和有效方法)
                  map a hexagonal grid in matplotlib(在 matplotlib 中映射六边形网格)
                  Execute arbitrary python code remotely - can it be done?(远程执行任意 python 代码 - 可以吗?)
                  Python - Plotting colored grid based on values(Python - 根据值绘制彩色网格)
                  Is there a GUI design app for the Tkinter / grid geometry?(是否有 Tkinter/网格几何图形的 GUI 设计应用程序?)
                  tkinter Canvas Scrollbar with Grid?(带有网格的 tkinter 画布滚动条?)
                  • <bdo id='JcxGn'></bdo><ul id='JcxGn'></ul>
                  • <legend id='JcxGn'><style id='JcxGn'><dir id='JcxGn'><q id='JcxGn'></q></dir></style></legend>
                    <tfoot id='JcxGn'></tfoot>

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

                            <tbody id='JcxGn'></tbody>

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