shell单引号下双引号如何做变量替换 '"$x"'

问题

curl 里写的是 "${server_group_ID}" 这种格式,但shell 不会在单引号 '...' 内做变量替换。单引号是“原子级别保护罩”,里面的内容全部视为纯文本。

思路

Bash 的变量替换只会在以下情况下生效:

  • 使用双引号 "..."
  • 不使用引号

所以你需要把 JSON 外层改为双引号,然后内部用 \" 转义字符串,或使用 EOF 模式自动避免转义地狱

推荐方式一:双引号并转义(最常见写法)

1
2
3
4
5
6
7
8
9
curl -s -XPOST "http://192.168.2.126:12346/alb/service/modify" \
--header "Content-Type: application/json" \
--data "{
\"server_group_id\": \"${server_group_ID}\",
\"server_id\": \"${server_ID}\",
\"server_type\": \"Ecs\",
\"weight\": 0,
\"port\": ${porT}
}"

推荐方式二:EOF,无脑成功(更适合 DevOps 场景)

1
2
3
4
5
6
7
8
9
10
11
12
curl -s -XPOST "http://192.168.2.126:12346/alb/service/modify" \
--header "Content-Type: application/json" \
--data @<(cat <<EOF
{
"server_group_id": "${server_group_ID}",
"server_id": "${server_ID}",
"server_type": "Ecs",
"weight": 0,
"port": ${porT}
}
EOF
)

推荐方式三:jq 构建 JSON(更安全、不会因为转义出错)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
json=$(jq -n \
--arg sg "$server_group_ID" \
--arg sid "$server_ID" \
--argjson port "$porT" \
'{
server_group_id: $sg,
server_id: $sid,
server_type: "Ecs",
weight: 0,
port: $port
}')

curl -s -XPOST "http://192.168.2.126:12346/alb/service/modify" \
--header "Content-Type: application/json" \
--data "$json"

延展视角

在 DevOps 自动化链路里,避免单引号导致的变量不替换是常见坑;一旦 JSON 变复杂或嵌套层级多,jq 方式会显著减少错误率,特别是在 CI/CD 环境。