含空格与短横线的文件名导致Bash脚本FFmpeg执行异常的问题排查
含空格与短横线的文件名导致Bash脚本FFmpeg执行异常的问题排查
兄弟,我太懂这种盯着本该简单的脚本抓耳挠腮的滋味了!你怀疑文件名里的空格和短横线是问题根源,这个判断完全正确——咱们来拆解下问题到底出在哪,再给你搞定它。
问题根源分析
你当前脚本里的find $SRCDIR -iname "*.mp4" | while read SRC这行是核心坑点:
read命令默认会把空格、制表符、换行符都当成字段分隔符,当文件名里有空格时,它会把完整的文件名拆成好几个片段,SRC变量每次只拿到其中一段,比如FINANCE - Big Hat No Cattle.mp4会被拆成FINANCE、-、Big等,这就导致ffmpeg收到的是不完整的路径,自然会报“找不到文件”,甚至出现路径半截截断的诡异情况。
另外你脚本里的DST变量处理有点冗余:先通过cut取第6个路径段,紧接着又用${SRC::-4}覆盖了它,其实完全可以用更可靠的参数替换来处理后缀。
修复后的完整脚本
#! /bin/bash SRCDIR=/var/www/virtual/site.name/large-videos # 用-print0和read -d ''处理带空格/特殊字符的文件名 find "$SRCDIR" -iname "*.mp4" -print0 | while IFS= read -r -d '' SRC do # 用参数替换去掉.mp4后缀,生成目标文件名 DST="${SRC%.mp4}" # 调用ffmpeg,所有变量都用双引号包裹 ffmpeg -i "$SRC" -vcodec libx264 -acodec aac -strict -2 -crf 28 "${DST}-small.mp4" done
关键修改点说明
find加上-print0:让find输出的每个文件名之间用空字符\0分隔,而不是默认的换行,这样即使文件名里有换行、空格都不会被拆分。while IFS= read -r -d '' SRC:IFS=确保读取时不会忽略开头的空格,-r禁止反斜杠转义,-d ''指定用空字符作为读取的分隔符,完美匹配find -print0的输出,保证完整读取每个文件名。"${SRC%.mp4}":这是bash的参数替换语法,意思是去掉SRC变量末尾的.mp4后缀,比cut或者字符串截取${SRC::-4}更可靠(比如遇到.MP4大写后缀也能处理,要是想兼容更多后缀,还能改成"${SRC%.*}"去掉任意类型的后缀)。- 所有变量都用双引号包裹:避免变量展开时被bash拆分,比如带空格的路径/文件名不会被当成多个参数。
这样修改后,不管文件名里有空格、短横线还是其他特殊字符,脚本都能正确处理啦!
备注:内容来源于stack exchange,提问作者davidgo
相关产品推荐
相关产品推荐

