Python 来自已完成子流程的stdout.read()有时返回空?
我创建了一个字典,其中我将id与子流程关联。 比如:Python 来自已完成子流程的stdout.read()有时返回空?,python,subprocess,stdout,status,Python,Subprocess,Stdout,Status,我创建了一个字典,其中我将id与子流程关联。 比如: cmd = "ls" processes[id] = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE) 然后我用这个流程图作为输入调用一个方法,检查哪个流程已经完成。如果进程完成,我将检查进程的stdout.read(),以查找特定的字符串匹配 问题有时是stdout.read()返回一个空值,这会导致字符串匹配出现问题 示例代码: #Create a map proce
cmd = "ls"
processes[id] = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
然后我用这个流程图作为输入调用一个方法,检查哪个流程已经完成。如果进程完成,我将检查进程的stdout.read()
,以查找特定的字符串匹配
问题有时是stdout.read()
返回一个空值,这会导致字符串匹配出现问题
示例代码:
#Create a map
processes[id] = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
...
#Pass that map to a method which checks which processes have finished
completedProcesses(processes)
def completedProcesses(processes):
processList = []
for id,process in processes.iteritems():
if process.poll() is not None:
#If some error in process stdout then print id
verifySuccessStatus(id, processes[id])
processList.add(id)
def verifySuccessStatus(id, process):
file=open(FAILED_IDS_FILE, 'a+')
buffer = process.stdout.read() #This returns empty value sometime
if 'Error' not in buffer:
file.write(id)
file.write('\n')
file.close()
我是python新手,我可能缺少对子流程的一些内部功能理解,您只是在阅读标准代码并查找“错误”。也许您还应该查看
stderr
:
processes[id] = subprocess.Popen(
[cmd],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
从:
子流程。STDOUT
一个特殊值,可用作Popen的stderr参数,并指示标准错误应与标准输出放在同一个句柄中
进程可能意外失败,返回的不是标准输出,而是非零返回代码。您可以使用process.returncode
检查此项
Popen.返回代码
子返回代码,由poll()和wait()设置(间接由communicate()设置)。None值表示进程尚未终止
负值-N表示子级被信号N终止(仅限Unix)
根据您的
ls
示例命令判断,您的问题可能是由标准输出管充满引起的。使用process.communicate()
方法为您处理此情况,因为您不需要多次写入stdin
# Recommend the future print function for easier file writing.
from __future__ import print_function
# Create a map
# Keeping access to 'stderr' is generally recommended, but not required.
# Also, if you don't know you need 'shell=True', it's safer practice not to use it.
processes[id] = subprocess.Popen(
[cmd],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
...
#Pass that map to a method which checks which processes have finished
check_processes(processes)
def check_processes(processes):
process_ids = []
# 'id' is a built-in function in python, so it's safer to use a different name.
for idx, process in processes.iteritems():
# When using pipes, communicate() will handle the case of the pipe
# filling up for you.
stdout, stderr = process.communicate()
if not is_success(stdout):
write_failed_id(idx)
process_ids.append(idx)
def is_success(stdout):
return 'Error' not in stdout
def write_failed_id(idx):
# Recommend using a context manager when interacting with files.
# Also, 'file' is a built-in function in python.
with open(FAILED_IDS_FILE, 'a+') as fail_file:
# The future print function makes file printing simpler.
print(idx, file=fail_file)
至少有两个问题:
process.stdout.read()
没有意义.read()
在EOF之前不会返回。它返回一个空字符串,以指示在此之后的EOF如果要同时运行多个外部进程,并在完成后检查其输出,请参阅。检查代码部分格式您的意思是“error”而不是“error”吗注意缺少的引号esplz将其读取为“error”不在缓冲区中:@AFH大多数用户无法进行单字符编辑。但是,您可以作为原始海报进行编辑,将其更正为“错误”。您确实意识到check_输出将执行大多数代码正在执行的操作,并且不需要shell=True?输出在标准输出中。我有时看到缓冲区,但有时它是空的。即使进程终止,缓冲区是否仍保持完好?@AFH我不知道。您是否希望进程终止?这不是最初的问题,所以只是想知道,因为这是一个有趣的可能性。您是否检查了流程返回代码?如果您不希望进程终止,它将告诉您哪个信号终止了它。