Bash脚本中动态构建JSON参数执行失败,如何正确转义字符串?
解决Shell脚本中RabbitMQAdmin JSON参数转义执行错误的问题
这个问题我太熟悉了——你遇到的是Shell脚本中命令字符串拼接时的参数拆分陷阱。当你把完整命令存在变量里再执行时,Bash的参数解析逻辑和你手动敲命令时完全不一样,这才导致JSON参数被错误解析。
问题根源
你echo出来的命令看起来没问题,但当脚本执行$COMPLEX_CMD时,Bash会把整个字符串按空格拆分,原来包裹JSON的单引号会被当成参数的一部分(也就是rabbitmqadmin实际收到的参数是'{"x-message-ttl":...}',带了单引号),自然就触发了JSON解析错误。
正确解决方案:用数组存储命令参数
处理复杂命令参数的标准做法是使用数组,它能完美保留每个参数的边界,不会破坏引号内的内容。修改后的脚本如下:
#!/bin/bash VHOST=$1 EXCHANGE=$2 DELAY=$3 # 用数组定义基础RabbitMQ命令 RABBIT_CMD=(docker exec rabbit rabbitmqadmin -u rabbit -p rabbit --vhost="$VHOST") # 构建完整命令数组,每个参数作为独立元素 COMPLEX_CMD=( "${RABBIT_CMD[@]}" declare queue name="${EXCHANGE}-delay" arguments="{\"x-message-ttl\":$DELAY,\"x-dead-letter-exchange\":\"$EXCHANGE\", \"x-dead-letter-routing-key\":\"worker\"}" ) # 调试用:打印格式化后的命令(可选) printf '%q ' "${COMPLEX_CMD[@]}" echo # 执行命令 "${COMPLEX_CMD[@]}"
关键说明:
- 数组
RABBIT_CMD将基础命令的每个空格分隔部分作为独立元素,避免后续拼接时的参数混乱 COMPLEX_CMD继承基础命令的所有元素,再依次添加declare queue、队列名、JSON参数,其中JSON字符串作为单独的一个元素,内部双引号已正确转义- 执行时使用
"${COMPLEX_CMD[@]}",Bash会将数组的每个元素作为独立参数传递,完全保留参数的原始内容
不推荐的替代方案(仅作参考)
如果你坚持想用字符串方式执行(存在安全风险,比如参数含特殊字符时易出问题),可以用eval来强制解析引号:
eval "$COMPLEX_CMD"
但这种方式容易引入注入风险,除非你能100%确保所有输入参数的安全性,否则优先选择数组方案。
内容的提问来源于stack exchange,提问作者Torsten Fehre
相关产品推荐
相关产品推荐

