Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用popen在stdout旁边内联解析stderr_Python_Python 3.x - Fatal编程技术网

Python 使用popen在stdout旁边内联解析stderr

Python 使用popen在stdout旁边内联解析stderr,python,python-3.x,Python,Python 3.x,下面的Python3代码中需要更改哪些特定语法才能在输出时有条件地处理来自stderr的文本输出? 当运行下面的函数时,只要在运行时的stdout输出行中找到someString,程序就能够执行某些操作 问题是stderr也会打印到命令行,但是stderr输出不会通过任何字符串解析代码进行处理,就像下面为stdout看到的那样 def runCommand(commandToRun, workingDir ): proc = subprocess.Popen( commandToRun,cw

下面的Python3代码中需要更改哪些特定语法才能在输出时有条件地处理来自
stderr
的文本输出?

当运行下面的函数时,只要在运行时的
stdout
输出行中找到
someString
,程序就能够
执行某些操作

问题是
stderr
也会打印到命令行,但是
stderr
输出不会通过任何字符串解析代码进行处理,就像下面为
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
我知道两种解决方案:

  • 使用
    Popen
    中的
    stderr=subprocess.stdout
    stderr
    重定向到
    stdout
    ,然后您可以在
    proc.stdout
    中获取所有内容 请参见下面的
    main redirect.py

  • 使用
    stderr=subprocess.PIPE
    将其放入
    proc.sterr
    -因此您可以使用不同的方法处理
    stdout
    stderr
    -但是
    readline()
    会阻塞代码,因此需要
    select.select()
    在运行
    readline()
    之前,检查
    stdout
    stderr
    中是否有新数据。但我不确定
    select
    是否在Windows上工作-我只在Linux上检查了它。
    请参见下面的
    main select.py


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

    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
    
    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
    
    main select.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
    
    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
    


    Doc:,

    关于
    stderr=subprocess.PIPE
    和更高版本的
    proc.stderr.readline()
    ?最终重定向
    stderr=subprocess.STOUT
    ,您应该在
    proc.stdout.readline()中拥有所有内容
    @furas如何将您的建议与
    while True
    块集成?如果您在
    popen()
    中使用
    stderr=subprocess.STOUT
    ,则不必更改
    while True
    ,因为您应该在
    line=proc.stdout.readline()
    中获得所有内容。但如果您使用
    stderr=subprocess.PIPE
    则需要
    errline=proc.stderr.readline()
    ,但问题是
    readline()
    可能会阻塞代码,需要一些非阻塞方法来检查
    readline()
    或者可能需要
    select.select()
    测试是否有新数据要读取,然后使用
    readline()
    typo-必须是
    STDOUT
    :)