Python 使用popen在stdout旁边内联解析stderr
下面的Python3代码中需要更改哪些特定语法才能在输出时有条件地处理来自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
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
:)