如何在GraphQL的cURL POST请求JSON体中插入Bash变量
解决Bash中Curl JSON请求体变量替换及格式错误问题
我来帮你解决这个问题,你遇到的核心问题有两个:单引号内变量无法展开,以及here-doc生成的JSON包含换行符导致解析失败。下面是具体的解决方案和解释:
问题1:变量$utc_format未被正确替换
你最初的写法用了单引号包裹JSON内容,而Bash中单引号会完全保留字符串字面量,不会解析变量,所以$utc_format被直接当作字符串发送给API,而不是替换成实际的日期值。
解决方案1:转义双引号并使用双引号包裹JSON
把外层的单引号改成双引号,同时转义JSON内部的所有双引号(避免和外层双引号冲突),这样变量就能正常展开了:
#!/bin/bash utc_format=$(date -v-3d -v-5M -u +"%Y-%m-%dT%H:%M:%SZ") curl \ -X POST \ -H "Content-Type: application/json" \ -H "X-Auth-Email: email@email.com" \ -H "X-Auth-key: $API_KEY" \ --data "{\"query\": \"query { viewer { zones ( filter: { zoneTag_in: [ \\\"abcde12345\\\" ] } ) { firewallEventsAdaptive ( filter: { source: \\\"waf\\\" datetime_gt: \\\"$utc_format\\\" ruleId: \\\"123456\\\" action: \\\"simulate\\\" } orderBy: [ datetime_DESC ] limit: 100 ) { clientIP edgeResponseStatus metadata { key value } } } } }\"}" \ https://api.api.com/ \ | python -m json.tool >> curl_results
更优雅的解决方案:用printf构建JSON
大量转义双引号会让代码可读性变差,推荐用printf来插入变量,这样无需多层转义:
#!/bin/bash utc_format=$(date -v-3d -v-5M -u +"%Y-%m-%dT%H:%M:%SZ") # 用printf将变量插入JSON模板 post_data=$(printf '{"query": "query { viewer { zones ( filter: { zoneTag_in: [ \"abcde12345\" ] } ) { firewallEventsAdaptive ( filter: { source: \"waf\" datetime_gt: \"%s\" ruleId: \"123456\" action: \"simulate\" } orderBy: [ datetime_DESC ] limit: 100 ) { clientIP edgeResponseStatus metadata { key value } } } } }"}' "$utc_format") curl \ -X POST \ -H "Content-Type: application/json" \ -H "X-Auth-Email: email@email.com" \ -H "X-Auth-key: $API_KEY" \ --data "$post_data" \ https://api.api.com/ \ | python -m json.tool >> curl_results
问题2:here-doc生成的JSON包含换行符
你用here-doc时收到的invalid character '\n' in string literal错误,是因为here-doc会保留换行符,而JSON规范不允许字符串中出现未转义的换行符。
解决方案:移除here-doc中的换行符
可以通过管道配合tr命令去掉所有换行,同时确保here-doc不使用引号包裹(否则变量无法展开):
#!/bin/bash utc_format=$(date -v-3d -v-5M -u +"%Y-%m-%dT%H:%M:%SZ") generate_post_data() { cat <<EOF | tr -d '\n' {"query": "query { viewer { zones ( filter: { zoneTag_in: [ \"abcde12345\" ] } ) { firewallEventsAdaptive ( filter: { source: \"waf\" datetime_gt: \"$utc_format\" ruleId: \"123456\" action: \"simulate\" } orderBy: [ datetime_DESC ] limit: 100 ) { clientIP edgeResponseStatus metadata { key value } } } } }"} EOF } curl \ -X POST \ -H "Content-Type: application/json" \ -H "X-Auth-Email: email@email.com" \ -H "X-Auth-key: $API_KEY" \ --data "$(generate_post_data)" \ https://api.api.com/ \ | python -m json.tool >> curl_results
核心总结
- Bash单引号内的变量不会被解析,需要用双引号或
printf来实现变量替换; - JSON不允许存在未转义的换行符,用here-doc生成JSON时必须移除换行;
- 推荐使用
printf构建JSON请求体,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者jayteezer
相关产品推荐
相关产品推荐

