Bash脚本中执行带变量扩展的jq命令报错该如何解决?
问题根因
报错本质是shell引号解析机制和jq参数传递规则不匹配导致的,具体错误点如下:
- shell变量赋值不允许等号两侧有空格,
jq_args = "xxx"的写法会被shell识别为执行jq_args命令而非变量赋值操作,本身就存在语法错误。 - 你手动给jq过滤器外层套了单引号到变量中:单引号是shell语法,作用是阻止shell解析引号内的内容,不需要传递给jq,你把单引号塞入
jq_args变量中,jq会把单引号当成过滤器的一部分处理,直接触发非法字符错误。 - 调用未加双引号的
$jq_args时,shell会按空格拆分内容,破坏原有过滤器结构,导致jq接收到的参数不完整。
正确实现方案
方案1:使用jq原生--arg传参(最推荐,无转义风险)
jq本身提供了外部变量传入接口,完全不需要手动拼接字符串和处理引号逃逸问题,兼容所有包含特殊字符、空格的变量场景:
# 先定义你的shell变量 PET="some-new-pet" NAME="my-brand-new-pet" toy1="toy1" toy2="toy2" toy3="toy3" # 通过--arg将shell变量传入jq内部,jq中直接用$变量名访问 cat myfile.json | jq \ --arg pet "$PET" \ --arg name "$NAME" \ --arg t1 "$toy1" \ --arg t2 "$toy2" \ --arg t3 "$toy3" \ '.pets[$pet] += {PetInfo: {name: $name, toys: ["\($t1)-postfix", "\($t2)-postfix", "\($t3)-postfix"]}}'
注意:jq中动态键名必须用方括号[]包裹引用,不能直接写.pets.$pet,必须写成.pets[$pet]。
方案2:shell变量拼接过滤器(不推荐,仅作错误示例修正)
如果你一定要用shell拼接的方式实现,需要严格遵守引号规则:
# 等号两侧无空格,不要额外加外层单引号 jq_args=".pets.\"${PET}\" += {PetInfo: {name: \"${NAME}\"}, toys: [\"${toy1}-postfix\", \"${toy2}-postfix\", \"${toy3}-postfix\"]}" # 调用时给变量外层加双引号,避免shell按空格拆分内容 cat myfile.json | jq "$jq_args"
该方案仅适用于变量内容无特殊字符、空格的场景,变量包含双引号、换行等特殊字符时会触发转义错误,优先使用方案1。
内容的提问来源于stack exchange,提问作者user797963
相关产品推荐
相关产品推荐

