如何在遍历subprocess.stdout.readlines()时识别最后一行
实现给dataLineReceiver标记最后一行的修改方案
问题背景
现有代码通过execShellCmd执行shell命令,逐行读取标准输出并通过parseLine传递给dataLineReceiver,需要给dataLineReceiver增加一个布尔标识,告知当前行是否是输出的最后一行,以便执行后续收尾操作。
修改方案
核心思路:
- 进程运行中(
p.poll() is None)读取的行都不是最后一行,直接传False - 进程结束后,把剩余输出先存为列表,遍历的时候判断当前行是否是列表的最后一项,对应传
True或False
修改后的完整代码
from typing import Callable import subprocess import shlex def execShellCmd(self, dataLineReceiver: Callable = None): try: p = subprocess.Popen( shlex.split(self._cmd), shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=None, bufsize=0, cwd=self.cwd, text=True ) # 进程运行中读取的行都不是最后一行 while p.poll() is None: line = p.stdout.readline() self.parseLine(line, p.returncode, dataLineReceiver, last_line=False) # 读取剩余所有行并转为列表,方便判断最后一行 remaining_lines = p.stdout.readlines() total_lines = len(remaining_lines) for idx, line in enumerate(remaining_lines): # 判断是否是最后一行 is_last = (idx == total_lines - 1) self.parseLine(line, p.returncode, dataLineReceiver, last_line=is_last) p.stdout.close() return p.returncode except Exception as ex: print("Exception: {}".format(ex)) return -1
关键说明
- 需要同步修改
parseLine函数的定义,新增last_line参数,并在内部把这个参数传递给dataLineReceiver,示例:
def parseLine(self, line, returncode, dataLineReceiver, last_line=False): # 保留原有处理逻辑 if dataLineReceiver: dataLineReceiver(line, returncode, last_line) # 按实际参数顺序传递即可
- 进程结束后读取剩余行时,先转成列表才能获取总行数,通过
enumerate拿到索引,对比索引是否等于总行数-1来判断是否是最后一行。 - 进程运行中的行不可能是最后一行,直接传
False即可。
内容的提问来源于stack exchange,提问作者Stamper
相关产品推荐
相关产品推荐

