如何在Shell FOR循环中将数组变量$i正确写入JSON键值?
问题排查与解决:Bash循环中JSON里的数组变量$i无法替换
你遇到的核心问题是Bash中单引号的特性——单引号包裹的内容会被当作纯文本字符串,shell不会解析其中的变量(比如$i)。你的代码里,整个JSON payload被单引号包裹,里面的'$i'完全没被shell处理,自然就变成空值了。
错误原因拆解
看你的循环代码:
for i in ${ARRAY[*]} do cURL -k -v -H 'Content-type: application/json' -d '{"id":1,"method":"exec","params":[{"data":{"action":"get","resource":"/api/v2/monitor/XXX/XXX/XXX","target":["some/dir/'$i'"]},"url":"XXX"}],"session":"SESSION_KEY",}' done
这里有两个明显问题:
- 单引号嵌套导致变量无法解析:
-d参数的JSON用单引号包裹,里面的'$i'处于单引号内部,shell不会识别这个变量,直接原样输出(但因为单引号嵌套写法有误,最终变成了空)。 - 数组遍历写法不安全:
${ARRAY[*]}会把数组元素用系统默认的IFS(通常是空格)拼接成一个字符串,如果数组元素包含空格,遍历就会出错,应该用${ARRAY[@]}来逐个遍历元素。
解决方案
这里提供两种可靠的写法,避免引号嵌套的坑:
方法1:拼接单引号与双引号解析变量
把需要替换变量的部分用双引号包裹,其余部分用单引号,通过字符串拼接实现:
for i in "${ARRAY[@]}"; do curl -k -v -H 'Content-type: application/json' -d '{ "id":1, "method":"exec", "params":[{ "data":{ "action":"get", "resource":"/api/v2/monitor/XXX/XXX/XXX", "target":["some/dir/'"$i"'"] }, "url":"XXX" }], "session":"SESSION_KEY" }' done
关键部分是"some/dir/'"$i"'":先闭合单引号,用双引号包裹$i(让shell解析变量),再重新打开单引号拼接剩余内容。
方法2:用printf预先构建JSON(更清晰)
先通过printf的占位符%s替换变量,生成完整的JSON字符串,再传给curl,可读性更强,也不容易出错:
for i in "${ARRAY[@]}"; do json_payload=$(printf '{ "id":1, "method":"exec", "params":[{ "data":{ "action":"get", "resource":"/api/v2/monitor/XXX/XXX/XXX", "target":["some/dir/%s"] }, "url":"XXX" }], "session":"SESSION_KEY" }' "$i") curl -k -v -H 'Content-type: application/json' -d "$json_payload" done
额外提醒
- 始终用
"${ARRAY[@]}"遍历数组,确保每个元素被正确处理(即使元素含空格)。 - 如果JSON内容复杂或包含特殊字符,推荐用专门的工具(比如
jq)来生成JSON,避免手动拼接引号的麻烦。
内容的提问来源于stack exchange,提问作者faceless
相关产品推荐
相关产品推荐

