curl命令POST请求JSON payload安全变量替换方法咨询
看起来你遇到的问题是shell变量展开时破坏了JSON的结构——当NEWUSERDISPLAYNAME包含空格时,shell会把它拆分成多个参数,导致最终发送的JSON出现语法错误(比如"displayName": "John" Doe"这种非法格式)。下面给你几个可靠的解决方案:
方法1:使用Here Document(简单易读)
这种方式让你直接编写格式清晰的JSON,变量会被正确展开,空格等特殊字符也能被保留:
curl -s -X POST "$APISERVER/users" \ -H 'Content-Type: application/json' \ -d @- <<EOF { "username": "$NEWUSERNAME", "firstName": "$NEWUSERFIRSTNAME", "lastName": "$NEWUSERLASTNAME", "displayName": "$NEWUSERDISPLAYNAME", "password": "$NEWUSERPASSWORD" } EOF
这里的@-告诉curl从标准输入读取请求体,Here Document(<<EOF到EOF之间的内容)里的变量会被shell正确展开,而且整个JSON结构不会被分词破坏。
方法2:用jq生成合法JSON(最安全,推荐)
如果你的系统安装了jq(大多数Linux发行版都可以通过包管理器安装),这是处理JSON变量替换最稳妥的方式——它会自动处理JSON的转义规则,哪怕变量里包含引号、换行符等特殊字符也没问题:
curl -s -X POST "$APISERVER/users" \ -H 'Content-Type: application/json' \ -d "$(jq -n \ --arg un "$NEWUSERNAME" \ --arg fn "$NEWUSERFIRSTNAME" \ --arg ln "$NEWUSERLASTNAME" \ --arg dn "$NEWUSERDISPLAYNAME" \ --arg pw "$NEWUSERPASSWORD" \ '{username: $un, firstName: $fn, lastName: $ln, displayName: $dn, password: $pw}')"
jq的--arg参数会把shell变量转换为合法的JSON字符串,自动处理所有转义需求,完全避免手动拼接JSON的各种坑。
方法3:手动转义并正确引用(不推荐,易出错)
如果你坚持手动拼接JSON,必须确保整个请求体被双引号包裹,同时内部的JSON引号用反斜杠转义,这样shell会把整个JSON当作单一参数处理:
curl -s -X POST "$APISERVER/users" \ -H 'Content-Type: application/json' \ -d "{ \"username\": \"$NEWUSERNAME\", \"firstName\": \"$NEWUSERFIRSTNAME\", \"lastName\": \"$NEWUSERLASTNAME\", \"displayName\": \"$NEWUSERDISPLAYNAME\", \"password\": \"$NEWUSERPASSWORD\" }"
这种方式虽然可行,但一旦变量里包含特殊字符(比如双引号),还是会出问题,所以只适合简单场景。
为什么原来的写法会出错?
你原来的代码用单引号包裹JSON片段,然后插入变量('...'"$VAR"'...'),当变量包含空格时,shell会把展开后的内容拆分成多个参数传给curl的-d选项,导致最终发送的JSON变成类似"displayName": "John" Doe"的非法格式,服务器自然会返回JSON解析错误。
内容的提问来源于stack exchange,提问作者Web User

