繁体   English   中英

使用 popen 在标准输出旁边解析标准错误

[英]Parse stderr inline alongside stdout using popen

为了有条件地处理来自stderr的文本 output,因为它是 output,需要在下面的 Python3 代码中更改哪些特定语法?

当运行下面的 function 时,只要在运行期间在stdout output 的行中找到someString时,程序就可以Do something操作。

问题是stderr也被打印到命令行,但stderr output 不是通过任何字符串解析代码处理的,如下面的stdout

def runCommand(commandToRun, workingDir ):
  proc = subprocess.Popen( commandToRun,cwd=workingDir,stdout=subprocess.PIPE, shell=True)
  while True:
    line = proc.stdout.readline()
    if line:
      thetext=line.decode('utf-8').rstrip('\r|\n')
      decodedline=ansi_escape.sub('', thetext)
      print(decodedline)
      if "someString" in decodedline:
        print("Do something!")
    else:
      break

我知道两种解决方案:

  1. proc.stdout中使用stderr=subprocess.STDOUT subprocess.STDOUT 将stderr重定向到stdout ,然后您可以在Popen中获取所有内容。
    请参阅main-redirect.py

  2. 使用stderr=subprocess.PIPE subprocess.PIPE 在proc.sterr中获取它 - 因此您可以使用不同的方法来处理stdoutstderr - 但是readline()会阻止代码,因此它需要select.select()来检查stdout中是否有新数据或运行readline()之前的stderr 但我不确定select是否适用于 Windows - 我只在 Linux 上检查过它。
    请参阅main-select.py


test.py - 它在stdoutstderr上生成文本,我将在其他脚本中捕获这些文本。

import sys
import time

i = 0
for _ in range(10):
    i += 1
    #sys.stdout.write('stdout {}\n'.format(i))
    #sys.stdout.flush()
    print('stdout {}'.format(i), file=sys.stdout, flush=True)
    time.sleep(0.5)
    
    i += 1
    #sys.stderr.write('STDERR {}\n'.format(i))
    #sys.stderr.flush()
    print('STDERR {}'.format(i), file=sys.stderr, flush=True)
    time.sleep(0.5)

main-redirect.py

import subprocess

p = subprocess.Popen('python3 test.py', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)

while True:
    line = p.stdout.readline()
    if line:
        print('STDOUT >>>', line.decode(), end='')
    else:
        break

main-select.py

import subprocess
import select

p = subprocess.Popen('python3 test.py', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

while True:
    # check if there are new data to read
    result = select.select([p.stdout, p.stderr], [], [])
    
    if p.stdout in result[0]:
        line = p.stdout.readline()
        if line:
            print('STDOUT >>>', line.decode(), end='')
        else:
            break

    if p.stderr in result[0]:
        line = p.stderr.readline()
        if line:
            print('STDERR >>>', line.decode(), end='')
        else:
            break

文档:进程, select

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM