【问题标题】:Python subprocess get output as process finishesPython子进程在进程完成时获取输出
【发布时间】:2013-08-18 08:52:39
【问题描述】:

目前,我通过蓝牙从设备获取 MAC 地址,并且一次将这些 MAC 地址传递给调用子进程并将输出分配给变量的方法。使用该变量,我运行一些过滤函数以从子进程中调用的命令中获取值。然后,如果它从输出中找到该值,则返回该值。

我想做的是一次将所有mac地址传递给方法并一次运行它们。如何捕获每个进程的输出并在进程完成时运行我的过滤脚本,同时在进程失败或错误时通知我。

这是一次处理一个 mac 的当前方法。现在让我们假设我正在传递一个 mac 地址列表。

 def getchan(mac):
  a = subprocess.Popen(["sdptool", "search","--bdaddr", mac, "OPUSH"], stdout = subprocess.PIPE).communicate()[0].split()[2:]
  if a==[]:
      print "ERROR"
      return "ERROR"
  else:
      count = 0
      for item in a:
          if item == "Channel:":
              return a[count + 1]
          count += 1
      return "Could not find the OPUSH channel"

它应该看起来像

def getchan(macs):
processes = set()
for mac in macs:
  processes.add(subprocess.Popen(["sdptool", "search","--bdaddr", mac, "OPUSH"], stdout =      subprocess.PIPE).communicate()[0].split()[2:])
  #this is where I need the help

感谢您观看。任何对子流程的帮助或澄清将不胜感激。

【问题讨论】:

    标签: python operating-system subprocess popen


    【解决方案1】:

    以可移植方式从子进程并行获取输出的最简单方法是使用线程:

    from multiprocessing.dummy import Pool # use threads
    from subprocess import check_output
    
    def getchan_mp(mac):
        try:
            output = check_output(["sdptool", "search","--bdaddr", mac, "OPUSH"])
            result = parse(output)
            return result, mac, None
        except Exception as err:
            return None, mac, err
    
    results = Pool(processes=len(macs)).map(getchan_mp, macs)
    failed_macs = [mac for result, mac, error in results if error is not None]
    

    【讨论】:

      【解决方案2】:
      import select
      import subprocess
      
      def in_parallel(processes):
          pipes = {p.stdout.fileno(): (i, p.stdout) for i, p in enumerate(processes)}
      
          poller = select.poll()
          for fd, pipe in pipes.iteritems():
              poller.register(fd, select.POLLIN)
      
          outputs = [''] * len(processes)
      
          while pipes:
              active = poller.poll()
              for fd, event in active:
                  idx, pipe = pipes[fd]
                  o = pipe.read()
                  if o:
                      outputs[idx] += o
                  else:
                      poller.unregister(fd)
                      pipe.close()
                      del pipes[fd]
      
          for p in processes:
              p.wait()
      
          return outputs
      
      args = ['a', 'b', 'c']
      processes = [subprocess.Popen(['sleep 5; echo ' + arg], stdout=subprocess.PIPE, shell=True) for arg in args]
      outputs = in_parallel(processes)
      print outputs
      

      $ time python test.py
      ['a\n', 'b\n', 'c\n']
      
      real    0m5.042s
      user    0m0.016s
      sys 0m0.016s
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-08
        • 1970-01-01
        • 2011-09-08
        • 2021-01-18
        • 2016-07-21
        • 2015-01-21
        • 1970-01-01
        • 2022-01-22
        相关资源
        最近更新 更多