"""子进程运行并把 stdout/stderr 流式写入 loguru,便于查看 FishMeasure / FishAction 中间输出。""" from __future__ import annotations import os import subprocess from typing import Dict, List, Optional from loguru import logger def run_subprocess_with_log( cmd: List[str], *, cwd: str, env: Optional[Dict[str, str]] = None, log_name: str, ) -> subprocess.CompletedProcess[str]: """运行子进程,合并 stderr 到 stdout,按行输出到 loguru。 返回 CompletedProcess,stdout 为完整输出,便于失败时拼进异常信息。 """ proc = subprocess.Popen( cmd, cwd=cwd, env=env if env is not None else os.environ.copy(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, ) lines: List[str] = [] if proc.stdout is not None: for line in proc.stdout: lines.append(line) s = line.rstrip() if s: logger.info("[{}] {}", log_name, s) rc = proc.wait() out = "".join(lines) return subprocess.CompletedProcess(cmd, rc, out, "")