如何在bash脚本中通过jq向ffmpeg传递键值对参数?
在Bash脚本中用JQ传递JSON参数给FFmpeg的正确方案
我之前也踩过类似的坑——直接用JQ提取JSON参数传给FFmpeg时,经常因为空格、特殊字符或者数组参数处理不当导致各种报错。下面是经过验证的可靠方法,帮你避开那些常见问题:
先明确你的JSON结构(示例)
假设你的外部JSON文件config.json长这样(可以根据实际需求调整):
{ "input_file": "my video with spaces.mp4", "output_file": "encoded output.mp4", "video_codec": "libx264", "video_bitrate": "4M", "extra_options": ["-vf", "scale=1280:720", "-y", "-hide_banner"] }
核心要点:用JQ的@sh过滤器处理参数
JQ的@sh过滤器会自动把JSON值转换成符合Shell语法的字符串——它会给带空格/特殊字符的内容加上单引号,避免Shell错误拆分参数,这是解决问题的关键。
方法1:分步提取参数(更易调试)
#!/bin/bash # 先检查JSON文件是否存在 if [ ! -f "config.json" ]; then echo "Error: config.json not found!" exit 1 fi # 提取单个参数,用@sh处理后通过eval自动解析引号 eval "$(jq -r '@sh "INPUT=\(.input_file) OUTPUT=\(.output_file) VCODEC=\(.video_codec) BITRATE=\(.video_bitrate)"' config.json)" # 提取数组类型的额外参数,转成Shell数组 mapfile -t EXTRA_OPTS < <(jq -r '.extra_options[] | @sh' config.json) # 调用FFmpeg——注意所有变量用双引号包裹,数组用${数组[@]}展开 ffmpeg -i "$INPUT" -c:v "$VCODEC" -b:v "$BITRATE" "${EXTRA_OPTS[@]}" "$OUTPUT"
方法2:一次性生成完整FFmpeg参数(更简洁)
如果你的JSON结构直接对应FFmpeg的参数逻辑,还可以让JQ直接生成所有参数:
#!/bin/bash # 从JSON生成FFmpeg的完整参数列表,用@sh确保格式正确 FFMPEG_ARGS=$(jq -r '[ "-i", .input_file, "-c:v", .video_codec, "-b:v", .video_bitrate ] + .extra_options + [ .output_file ] | map(@sh) | join(" ")' config.json) # 执行FFmpeg命令 eval "ffmpeg $FFMPEG_ARGS"
常见报错的原因及解决手段
- 带空格的文件名被拆成多个参数
- 解决:必须用
@sh处理参数,且在Shell中用双引号包裹变量,数组用${数组[@]}展开。
- 解决:必须用
- 数组参数直接拼接导致格式混乱
- 解决:用
mapfile把JQ输出的数组元素转成Shell数组,不要直接用$(jq ...)拼接。
- 解决:用
- 特殊字符(如&、$)被Shell提前解析
- 解决:
@sh会自动给这类内容加上单引号,避免Shell误解析,一定要启用这个过滤器。
- 解决:
内容的提问来源于stack exchange,提问作者C.Astraea
相关产品推荐
相关产品推荐

