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

Bash中如何捕获编辑后的脚本输出并实时打印到控制台?

实时编辑程序输出、打印并捕获到变量的解决方案

针对yt-dlp、rsync这类长耗时程序,要实现编辑输出后实时打印到控制台,同时将编辑后的内容捕获到变量,可以通过以下方式解决缓冲和输出分流的问题:

核心思路

问题的关键在于管道工具(如sed)默认会使用块缓冲,导致输出无法实时刷新到控制台。我们需要强制工具使用行缓冲,同时通过tee将编辑后的输出分流到控制台和变量捕获管道。

具体实现(以yt-dlp为例)

方法1:用stdbuf强制行缓冲

# 保存当前标准输出的文件描述符
exec 3>&1

# 捕获编辑后的输出到变量,同时实时打印到控制台
captured_output=$(yt-dlp -s https://www.youtube.com/playlist?list=PL-cwa6ZvflaA7qryuX_m6Vyqt7ZwMi6xl 2>&1 \
    | stdbuf -oL sed -rn 's/.*((http.+)|^(WARNING|ERROR).+)/\1/gp' \
    | tee >(cat >&3))

# 可选:恢复文件描述符(脚本结束后会自动关闭,可省略)
exec 3>&-

方法2:用GNU sed的-u参数(无缓冲模式)

如果使用GNU sed,也可以直接用-u选项替代stdbuf:

exec 3>&1
captured_output=$(yt-dlp -s https://www.youtube.com/playlist?list=PL-cwa6ZvflaA7qryuX_m6Vyqt7ZwMi6xl 2>&1 \
    | sed -urn 's/.*((http.+)|^(WARNING|ERROR).+)/\1/gp' \
    | tee >(cat >&3))
exec 3>&-

适配rsync的示例

同样的逻辑可以直接套用到rsync:

exec 3>&1
rsync_output=$(rsync -avz source/ destination/ 2>&1 \
    | stdbuf -oL sed -n 's/^sent //p' \
    | tee >(cat >&3))
exec 3>&-

关键说明

  1. 缓冲处理:stdbuf -oL强制后续命令(sed)使用行缓冲,每处理一行就输出一行,确保实时性;GNU sed的-u参数直接开启无缓冲模式,效果一致。
  2. 输出分流:tee >(cat >&3)将编辑后的内容同时发送到两个地方:一个是命令替换的管道(用于捕获到变量),另一个是之前保存的标准输出(控制台)。
  3. 文件描述符:exec 3>&1保存当前的标准输出,避免tee直接输出到命令替换的管道导致控制台无输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:12:40