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

为何重定向ffmpeg stderr到stdout时Bash会吃掉输入隔行首字母?

循环读取文件名时部分文件名首字母缺失(仅配合ffmpeg处理真实文件时出现)

问题重现

脚本代码:

#!/bin/bash

while read -r filename; do
  echo $filename
  cmd_out=$(ffmpeg -i "$filename" -f null - 2>&1)
done < inputs.txt

输入文件inputs.txt内容:

intro.mp3
silence.mp3
outro.mp3
intro2.mp3

实际输出:

intro.mp3
ilence.mp3
outro.mp3
ntro2.mp3

可见silence.mp3和intro2.mp3的首字母丢失。

原因分析

ffmpeg默认会尝试从标准输入(stdin)读取数据,而你的脚本中while read是通过stdin读取inputs.txt的行内容。当第一个循环执行ffmpeg时,ffmpeg会读取stdin中剩余的内容,吃掉了下一行的第一个字符,导致下一次read只能读到缺少首字母的文件名。

只有当文件真实存在时,ffmpeg完成文件分析后才会触发读取stdin的行为;如果文件不存在,ffmpeg直接报错退出,不会读取stdin,因此不会出现该问题。

解决办法

方法1:禁止ffmpeg读取stdin

使用ffmpeg的-nostdin参数,明确阻止它读取标准输入:

#!/bin/bash

while read -r filename; do
  echo $filename
  cmd_out=$(ffmpeg -nostdin -i "$filename" -f null - 2>&1)
done < inputs.txt

方法2:将ffmpeg的stdin重定向到空设备

把ffmpeg的输入源指向/dev/null,让它无数据可读:

#!/bin/bash

while read -r filename; do
  echo $filename
  cmd_out=$(ffmpeg -i "$filename" -f null - 2>&1 < /dev/null)
done < inputs.txt

方法3:使用独立文件描述符读取输入文件

给inputs.txt分配单独的文件描述符(比如3),让read从该描述符读取内容,避免与ffmpeg的stdin冲突:

#!/bin/bash

while read -r filename <&3; do
  echo $filename
  cmd_out=$(ffmpeg -i "$filename" -f null - 2>&1)
done 3< inputs.txt

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:52:12