Docker中运行含ffmpeg的Bash查找循环时出现异常行为
解决Docker中FLAC转WAV脚本的异常问题
我来帮你排查Docker里运行FLAC转码脚本的异常问题,先梳理下你的环境配置,再逐个分析可能的问题和修复办法:
你的环境配置
Dockerfile
FROM debian:9 WORKDIR /app RUN apt-get -y update && \ apt-get -y install ffmpeg curl COPY . /app
run.sh脚本
#!/bin/bash find /pfs/in -maxdepth 1 -name "*.flac" -print0 | while IFS= read -r -d $'\0' inFile; do echo "\n##### Process '${inFile}' #####" ffmpeg -y -i ${inFile} -ar 16000 tmp.wav # use 16kHz - default for EML done
常见异常原因及修复方案
1. 挂载路径不匹配
脚本里指定了/pfs/in作为FLAC文件的读取目录,但如果启动容器时没有把本地文件挂载到这个路径,find命令根本找不到目标文件。
- 修复方式:
要么启动容器时正确挂载到/pfs/in:
要么修改脚本里的路径为你实际挂载的目录(比如docker run -v /本地FLAC文件目录:/pfs/in 你的镜像名称/app/in)。
2. 文件权限缺失
挂载的FLAC文件可能存在权限不足的情况,容器内用户无法读取;或者tmp.wav的写入路径没有权限。
- 修复方式:
- 挂载时确保本地文件有可读权限,或者启动容器时加上
--user root(如果后续切换了非root用户)。 - 把输出文件指定到有写入权限的目录,比如
/app/tmp.wav(因为WORKDIR是/app,这里默认有写入权限)。
- 挂载时确保本地文件有可读权限,或者启动容器时加上
3. 脚本未添加执行权限
你把run.shCOPY到容器后,如果本地脚本没有执行权限,容器内的脚本也无法运行。
- 修复方式:
- 本地先给脚本加权限:
chmod +x run.sh,再构建镜像。 - 或者在Dockerfile里添加执行权限配置:
RUN chmod +x /app/run.sh。
- 本地先给脚本加权限:
4. 变量未加引号导致文件名解析错误
如果FLAC文件名包含空格或特殊字符,${inFile}不加引号会让ffmpeg无法正确识别文件路径。
- 修复方式:把
${inFile}改成"${inFile}",命令调整为:ffmpeg -y -i "${inFile}" -ar 16000 /app/tmp.wav
5. 多文件覆盖输出结果
当前脚本处理每个FLAC都输出到同一个tmp.wav,后面的文件会直接覆盖前面的,最终只保留最后一个转换结果。
- 修复方式:根据输入文件名生成对应的输出文件,避免覆盖:
outFile="/app/$(basename "${inFile}" .flac).wav" ffmpeg -y -i "${inFile}" -ar 16000 "${outFile}"
6. Debian 9源失效(可选)
Debian 9是旧版本,默认apt源可能已经失效,导致构建镜像时安装ffmpeg失败。
- 修复方式:修改Dockerfile更换为归档源:
FROM debian:9 WORKDIR /app RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list && \ sed -i 's/security.debian.org/archive.debian.org/g' /etc/apt/sources.list && \ apt-get -y update && \ apt-get -y install ffmpeg curl COPY . /app
完整修复后的示例
修复后的Dockerfile
FROM debian:9 WORKDIR /app RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list && \ sed -i 's/security.debian.org/archive.debian.org/g' /etc/apt/sources.list && \ apt-get -y update && \ apt-get -y install ffmpeg curl && \ chmod +x /app/run.sh COPY . /app CMD ["/app/run.sh"]
修复后的run.sh
#!/bin/bash # 创建输出目录避免报错 mkdir -p /app/output find /pfs/in -maxdepth 1 -name "*.flac" -print0 | while IFS= read -r -d $'\0' inFile; do echo -e "\n##### Process '${inFile}' #####" # 生成与输入文件名对应的输出文件 outFile="/app/output/$(basename "${inFile}" .flac).wav" ffmpeg -y -i "${inFile}" -ar 16000 "${outFile}" done
启动容器时记得挂载输入和输出目录:
docker run -v /本地FLAC目录:/pfs/in -v /本地输出目录:/app/output 你的镜像名称
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

