Shell脚本中使用CURL循环发送JSON数组作为POST请求体报错解决
解决Shell脚本遍历JSON数组并发送POST请求的400错误问题
出现400错误(提示JSON输入意外结束)的核心原因是:用非JSON专用工具拆分数组时破坏了JSON结构,比如用普通for循环、grep/sed等工具处理JSON,会把带空格、引号的JSON对象拆分成多个片段,导致curl收到不完整的请求体。
正确解决方案:用jq处理JSON(推荐)
jq是专门的JSON解析工具,能保证每个数组元素都是完整的JSON对象,不会破坏结构。
示例步骤:
- 假设你的
data.json内容如下:
[ {"id": 1, "content": "test1"}, {"id": 2, "content": "test2 with space"}, {"id": 3, "content": "test\"quote\""} ]
- 编写正确的Shell脚本:
#!/bin/bash # 用jq遍历JSON数组,输出单行紧凑格式的每个元素 jq -c '.[]' data.json | while read -r json_item; do # 发送POST请求,将完整的JSON对象作为请求体 curl -X POST \ -H "Content-Type: application/json" \ -d "$json_item" \ https://your-target-api.com/endpoint done
关键细节说明:
-c:让jq输出单行紧凑格式的JSON,避免换行导致read命令读取不完整read -r:禁用shell的转义处理,保证JSON里的特殊字符(比如引号、反斜杠)不被篡改- 双引号包裹
$json_item:确保整个JSON对象作为一个完整参数传给curl -d,不会被shell按空格拆分
常见错误的原因(避坑)
如果之前用了类似下面的错误写法,就会触发400:
# 错误写法:用for循环直接遍历,shell会按空格拆分JSON对象 for item in $(jq '.[]' data.json); do curl -d $item ... done
这种写法会把{"id":2,"content":"test2 with space"}拆成{"id":2,"content":"test2和with、space"}三个片段,curl收到的自然是残缺的JSON。
额外注意事项
- 确保系统已安装jq:Debian/Ubuntu执行
apt install jq,CentOS/RHEL执行yum install jq - 若API需要认证,在curl中添加对应请求头(比如
-H "Authorization: Bearer your-token") - 可添加
curl -v查看实际发送的请求体,验证是否正确
内容的提问来源于stack exchange,提问作者killjoy
相关产品推荐
相关产品推荐

