You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在遍历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

关键说明

  1. 需要同步修改parseLine函数的定义,新增last_line参数,并在内部把这个参数传递给dataLineReceiver,示例:
def parseLine(self, line, returncode, dataLineReceiver, last_line=False):
    # 保留原有处理逻辑
    if dataLineReceiver:
        dataLineReceiver(line, returncode, last_line)  # 按实际参数顺序传递即可
  1. 进程结束后读取剩余行时,先转成列表才能获取总行数,通过enumerate拿到索引,对比索引是否等于总行数-1来判断是否是最后一行。
  2. 进程运行中的行不可能是最后一行,直接传False即可。

内容的提问来源于stack exchange,提问作者Stamper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:20:09