Jenkins Pipeline中Curl返回无效JSON错误,Freestyle及本地运行正常
解决Jenkins Pipeline中调用AWS CLI封装API时的无效JSON错误
看起来你遇到的问题核心是在Jenkins Pipeline的shell脚本里手动拼接JSON请求体时,格式转义和多行内容破坏了JSON的合法性。Freestyle或者CentOS主机里能运行,是因为shell环境处理变量展开和换行的方式和Pipeline的shell执行环境略有不同,而且手动拼接JSON很容易因为转义、换行、特殊字符导致格式错误。
问题根源分析
你用jq生成的$template是完整的JSON对象,直接把它嵌入到curl的-d参数的JSON字符串里时,会出现两个关键问题:
$template包含换行符,直接嵌入后会让整个请求体变成多行,不符合JSON的格式要求(JSON允许换行但需要正确处理,而shell直接展开后会导致解析错误)- shell变量展开后,JSON里的双引号和外层JSON的双引号虽然语法上看似没问题,但实际执行时可能因为shell的词法解析导致请求体被拆分成多个部分,彻底破坏JSON结构
修复方案
推荐用jq来构造完整的请求体JSON,而不是手动拼接,这样能自动处理所有转义和格式问题。另外,避免在curl命令里直接嵌入复杂变量,改用标准输入传递JSON,彻底规避转义陷阱。
修改后的Pipeline脚本片段如下:
stage('Call our internal AWS CLI Wrapper System API to perform an ACTION on a specified ENVIRONMENT') { steps { script { if("${params.ENVIRONMENT}" == 'int' && "${params.ACTION}" == 'create'){ echo "ENVIRONMENT=${params.ENVIRONMENT}, ACTION=${params.ACTION}" echo "" sh '''#!/bin/bash # Create Neptune Cluster for the Int environment cd blah-db echo "Current working directory is $PWD" CLOUD_FORMATION_FILE=$PWD/infrastructure/templates/neptune-cluster.json echo "The CloudFormation file to operate on is $CLOUD_FORMATION_FILE" # 用jq直接构造完整的请求体JSON,避免手动拼接的转义问题 jq -n \ --arg aws_account "1111111111" \ --arg region "us-east-1" \ --arg name_suffix "cluster" \ --argjson template "$(jq -M '.Parameters.Env.Default="int"' "$CLOUD_FORMATION_FILE")" \ '{"aws_account": $aws_account, "region": $region, "name_suffix": $name_suffix, "template": $template}' \ | curl -d @- \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ https://base.api.url/v1/services/blah-neptune/int/stacks \ --cert /path/to/client/certificate/client.crt --key /path/to/client/private-key/client.key cd .. pwd # Set a timer to run for 300 seconds or 5 minutes to create a delay to allow for the Neptune Cluster to be fully provisioned first before adding instances to it. ''' } } } }
关键改进点
- 用jq构造合法JSON:通过
jq -n创建新的JSON对象,用--arg传递普通字符串参数,--argjson直接传递JSON类型的参数(这里把处理后的CloudFormation模板作为完整JSON对象传入),确保生成的请求体100%符合JSON规范。 - 管道传递JSON:用
| curl -d @-把jq输出的JSON通过标准输入传给curl,彻底避免了手动拼接时的转义错误和shell解析问题。 - 安全的变量引用:所有文件路径和变量都用双引号包裹,避免shell解析时出现意外的词法拆分。
额外调试建议
如果你需要验证生成的请求体是否正确,可以在jq命令后加上tee request.json,把生成的JSON保存到临时文件,方便查看:
jq -n \ --arg aws_account "1111111111" \ --arg region "us-east-1" \ --arg name_suffix "cluster" \ --argjson template "$(jq -M '.Parameters.Env.Default="int"' "$CLOUD_FORMATION_FILE")" \ '{"aws_account": $aws_account, "region": $region, "name_suffix": $name_suffix, "template": $template}' \ | tee request.json \ | curl -d @- \ ...
这样就能快速确认请求体的格式是否符合API要求,排除格式类问题。
内容的提问来源于stack exchange,提问作者sage
相关产品推荐
相关产品推荐

