<legend id='n4fmy'><style id='n4fmy'><dir id='n4fmy'><q id='n4fmy'></q></dir></style></legend>
    • <bdo id='n4fmy'></bdo><ul id='n4fmy'></ul>

  • <small id='n4fmy'></small><noframes id='n4fmy'>

    <tfoot id='n4fmy'></tfoot>

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

        在没有挂起的情况下停止在 Python 中读取进程输出?

        时间:2023-07-22
        <legend id='89FES'><style id='89FES'><dir id='89FES'><q id='89FES'></q></dir></style></legend>
          <tbody id='89FES'></tbody>
        <i id='89FES'><tr id='89FES'><dt id='89FES'><q id='89FES'><span id='89FES'><b id='89FES'><form id='89FES'><ins id='89FES'></ins><ul id='89FES'></ul><sub id='89FES'></sub></form><legend id='89FES'></legend><bdo id='89FES'><pre id='89FES'><center id='89FES'></center></pre></bdo></b><th id='89FES'></th></span></q></dt></tr></i><div id='89FES'><tfoot id='89FES'></tfoot><dl id='89FES'><fieldset id='89FES'></fieldset></dl></div>
        • <bdo id='89FES'></bdo><ul id='89FES'></ul>

          <small id='89FES'></small><noframes id='89FES'>

            <tfoot id='89FES'></tfoot>

                1. 本文介绍了在没有挂起的情况下停止在 Python 中读取进程输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有一个适用于 Linux 的 Python 程序,几乎看起来像这样:

                  I have a Python program for Linux almost looks like this one :

                  import os
                  import time
                  
                  process = os.popen("top").readlines()
                  
                  time.sleep(1)
                  
                  os.popen("killall top")
                  
                  print process
                  

                  程序挂在这一行:

                  process = os.popen("top").readlines()
                  

                  这发生在不断更新输出的工具中,例如Top"

                  and that happens in the tools that keep update outputting like "Top"

                  我最好的尝试:

                  import os
                  import time
                  import subprocess
                  
                  process = subprocess.Popen('top')
                  
                  time.sleep(2)
                  
                  os.popen("killall top")
                  
                  print process
                  

                  它比第一个效果更好(它被 kelled 了),但它返回了:

                  it worked better than the first one (it's kelled ), but it returns :

                  <subprocess.Popen object at 0x97a50cc>
                  

                  二审:

                  import os
                  import time
                  import subprocess
                  
                  process = subprocess.Popen('top').readlines()
                  
                  time.sleep(2)
                  
                  os.popen("killall top")
                  
                  print process
                  

                  与第一个相同.由于readlines()"而挂起

                  the same as the first one. It hanged due to "readlines()"

                  它的返回应该是这样的:

                  Its returning should be like this :

                  top - 05:31:15 up 12:12,  5 users,  load average: 0.25, 0.14, 0.11
                  Tasks: 174 total,   2 running, 172 sleeping,   0 stopped,   0 zombie
                  Cpu(s):  9.3%us,  3.8%sy,  0.1%ni, 85.9%id,  0.9%wa,  0.0%hi,  0.0%si,  0.0%st
                  Mem:   1992828k total,  1849456k used,   143372k free,   233048k buffers
                  Swap:  4602876k total,        0k used,  4602876k free,  1122780k cached
                  
                    PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
                  31735 Barakat   20   0  246m  52m  20m S 19.4  2.7  13:54.91 totem              
                   1907 root      20   0 91264  45m  15m S  1.9  2.3  38:54.14 Xorg               
                   2138 Barakat   20   0 17356 5368 4284 S  1.9  0.3   3:00.15 at-spi-registry    
                   2164 Barakat    9 -11  164m 7372 6252 S  1.9  0.4   2:54.58 pulseaudio         
                   2394 Barakat   20   0 27212 9792 8256 S  1.9  0.5   6:01.48 multiload-apple    
                   6498 Barakat   20   0 56364  30m  18m S  1.9  1.6   0:03.38 pyshell            
                      1 root      20   0  2880 1416 1208 S  0.0  0.1   0:02.02 init               
                      2 root      20   0     0    0    0 S  0.0  0.0   0:00.02 kthreadd           
                      3 root      RT   0     0    0    0 S  0.0  0.0   0:00.12 migration/0        
                      4 root      20   0     0    0    0 S  0.0  0.0   0:02.07 ksoftirqd/0        
                      5 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 watchdog/0         
                      9 root      20   0     0    0    0 S  0.0  0.0   0:01.43 events/0           
                     11 root      20   0     0    0    0 S  0.0  0.0   0:00.00 cpuset             
                     12 root      20   0     0    0    0 S  0.0  0.0   0:00.02 khelper            
                     13 root      20   0     0    0    0 S  0.0  0.0   0:00.00 netns              
                     14 root      20   0     0    0    0 S  0.0  0.0   0:00.00 async/mgr          
                     15 root      20   0     0    0    0 S  0.0  0.0   0:00.00 pm
                  

                  并保存在变量进程"中.任何我的想法伙计们,我现在真的被困住了吗?

                  and save in the variable "process". Any I idea guys, I'm really stuck now ?

                  推荐答案

                  #!/usr/bin/env python
                  """Start process; wait 2 seconds; kill the process; print all process output."""
                  import subprocess
                  import tempfile
                  import time
                  
                  def main():
                      # open temporary file (it automatically deleted when it is closed)
                      #  `Popen` requires `f.fileno()` so `SpooledTemporaryFile` adds nothing here
                      f = tempfile.TemporaryFile() 
                  
                      # start process, redirect stdout
                      p = subprocess.Popen(["top"], stdout=f)
                  
                      # wait 2 seconds
                      time.sleep(2)
                  
                      # kill process
                      #NOTE: if it doesn't kill the process then `p.wait()` blocks forever
                      p.terminate() 
                      p.wait() # wait for the process to terminate otherwise the output is garbled
                  
                      # print saved output
                      f.seek(0) # rewind to the beginning of the file
                      print f.read(), 
                      f.close()
                  
                  if __name__=="__main__":
                      main()
                  

                  只打印输出部分的类似尾巴的解决方案

                  您可以在另一个线程中读取进程输出并将所需数量的最后一行保存在队列中:

                  Tail-like Solutions that print only the portion of the output

                  You could read the process output in another thread and save the required number of the last lines in a queue:

                  import collections
                  import subprocess
                  import time
                  import threading
                  
                  def read_output(process, append):
                      for line in iter(process.stdout.readline, ""):
                          append(line)
                  
                  def main():
                      # start process, redirect stdout
                      process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
                      try:
                          # save last `number_of_lines` lines of the process output
                          number_of_lines = 200
                          q = collections.deque(maxlen=number_of_lines) # atomic .append()
                          t = threading.Thread(target=read_output, args=(process, q.append))
                          t.daemon = True
                          t.start()
                  
                          #
                          time.sleep(2)
                      finally:
                          process.terminate() #NOTE: it doesn't ensure the process termination
                  
                      # print saved lines
                      print ''.join(q)
                  
                  if __name__=="__main__":
                      main()
                  

                  这个变体要求 q.append() 是原子操作.否则输出可能会损坏.

                  This variant requires q.append() to be atomic operation. Otherwise the output might be corrupted.

                  您可以使用 signal.alarm() 在指定超时后调用 process.terminate() 而不是在另一个线程中读取.尽管它可能无法与 subprocess 模块很好地交互.基于 @Alex Martelli 的回答:

                  You could use signal.alarm() to call the process.terminate() after specified timeout instead of reading in another thread. Though it might not interact very well with the subprocess module. Based on @Alex Martelli's answer:

                  import collections
                  import signal
                  import subprocess
                  
                  class Alarm(Exception):
                      pass
                  
                  def alarm_handler(signum, frame):
                      raise Alarm
                  
                  def main():
                      # start process, redirect stdout
                      process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
                  
                      # set signal handler
                      signal.signal(signal.SIGALRM, alarm_handler)
                      signal.alarm(2) # produce SIGALRM in 2 seconds
                  
                      try:
                          # save last `number_of_lines` lines of the process output
                          number_of_lines = 200
                          q = collections.deque(maxlen=number_of_lines)
                          for line in iter(process.stdout.readline, ""):
                              q.append(line)
                          signal.alarm(0) # cancel alarm
                      except Alarm:
                          process.terminate()
                      finally:
                          # print saved lines
                          print ''.join(q)
                  
                  if __name__=="__main__":
                      main()
                  

                  这种方法只适用于 *nix 系统.如果 process.stdout.readline() 没有返回,它可能会阻塞.

                  This approach works only on *nix systems. It might block if process.stdout.readline() doesn't return.

                  import collections
                  import subprocess
                  import threading
                  
                  def main():
                      # start process, redirect stdout
                      process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
                  
                      # terminate process in timeout seconds
                      timeout = 2 # seconds
                      timer = threading.Timer(timeout, process.terminate)
                      timer.start()
                  
                      # save last `number_of_lines` lines of the process output
                      number_of_lines = 200
                      q = collections.deque(process.stdout, maxlen=number_of_lines)
                      timer.cancel()
                  
                      # print saved lines
                      print ''.join(q),
                  
                  if __name__=="__main__":
                      main()
                  

                  这种方法也应该适用于 Windows.在这里,我使用 process.stdout 作为可迭代对象;它可能会引入额外的输出缓冲,如果不需要,您可以切换到 iter(process.stdout.readline, "") 方法.如果进程没有在 process.terminate() 上终止,则脚本挂起.

                  This approach should also work on Windows. Here I've used process.stdout as an iterable; it might introduce an additional output buffering, you could switch to the iter(process.stdout.readline, "") approach if it is not desirable. if the process doesn't terminate on process.terminate() then the scripts hangs.

                  import collections
                  import subprocess
                  import sys
                  import time
                  
                  def main():
                      args = sys.argv[1:]
                      if not args:
                          args = ['top']
                  
                      # start process, redirect stdout
                      process = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
                  
                      # save last `number_of_lines` lines of the process output
                      number_of_lines = 200
                      q = collections.deque(maxlen=number_of_lines)
                  
                      timeout = 2 # seconds
                      now = start = time.time()    
                      while (now - start) < timeout:
                          line = process.stdout.readline()
                          if not line:
                              break
                          q.append(line)
                          now = time.time()
                      else: # on timeout
                          process.terminate()
                  
                      # print saved lines
                      print ''.join(q),
                  
                  if __name__=="__main__":
                      main()
                  

                  此变体既不使用线程,也不使用信号,但会在终端中产生乱码输出.如果 process.stdout.readline() 阻塞,它将阻塞.

                  This variant use neither threads, no signals but it produces garbled output in the terminal. It will block if process.stdout.readline() blocks.

                  这篇关于在没有挂起的情况下停止在 Python 中读取进程输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:修改环境的 Python 子进程/Popen 下一篇:使用子进程在 python 脚本中调用带有输入的 python 脚本

                  相关文章

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

                  <legend id='cdG01'><style id='cdG01'><dir id='cdG01'><q id='cdG01'></q></dir></style></legend>
                  • <bdo id='cdG01'></bdo><ul id='cdG01'></ul>

                    1. <small id='cdG01'></small><noframes id='cdG01'>