求助:编写Shell脚本结合jq从URL获取的JSON中提取字段
解决Shell脚本中JSON解析的后续处理问题
你的脚本已经成功拿到了JSON格式的cred变量,但后续用jq处理时的写法有误,导致无法正确解析。让我帮你梳理问题并给出修正方案:
问题分析
你代码里的这一行是核心错误:
access=$(jq -r "'$cred'")
这里存在两个关键问题:
- 直接把
$cred变量嵌入jq参数中,当JSON包含空格、引号或特殊字符时,Shell会自动拆分字符串、处理转义,导致jq接收到的是破碎的内容,无法识别合法的JSON结构。 - 单引号嵌套的写法不符合Shell语法,会让
jq接收到错误的参数指令。
另外,echo $cred也应该改成echo "$cred"——不加双引号的话,Shell会把JSON中的空格当作分隔符,直接破坏原有的JSON结构。
修正方案
方案1:通过管道传递JSON给jq
既然cred本身就是合法的JSON字符串,直接用管道把它传给jq处理即可,这是最直观的方式:
#!/bin/bash # 获取身份令牌 token=$(http POST :3000/signin/frontm user:='{"email": "sourav@frontm.com", "password": "Hello_789"}' | jq -r '.data.id_token') # 获取目标JSON数据 cred=$(http POST :3000/auth provider_name:frontm token:$token user:=@/tmp/user.json | jq '{ creds: .creds, userUuid: .user.userId }') # 正确输出完整JSON结构(必须加双引号) echo "$cred" # 通过管道传递给jq,提取你需要的字段(示例为creds) access=$(echo "$cred" | jq -r '.creds') echo "$access"
方案2:用jq的--argjson参数传递JSON变量
如果需要在jq中多次复用这个JSON变量,或者JSON内容特别复杂,推荐用--argjson直接传递完整的JSON对象,彻底避免转义问题:
#!/bin/bash token=$(http POST :3000/signin/frontm user:='{"email": "sourav@frontm.com", "password": "Hello_789"}' | jq -r '.data.id_token') cred=$(http POST :3000/auth provider_name:frontm token:$token user:=@/tmp/user.json | jq '{ creds: .creds, userUuid: .user.userId }') echo "$cred" # 使用--argjson将cred作为JSON对象传给jq,命名为cred_obj access=$(jq -r '.creds' --argjson cred_obj "$cred" <<< "$cred_obj") # 或者更简洁的写法,直接处理变量输入: # access=$(jq -r '.creds' <<< "$cred") echo "$access"
额外建议
- 所有包含空格、特殊字符的变量输出和传递,都要记得用双引号包裹(比如
echo "$cred"、token="$token"),避免Shell自动拆分字符串。 http命令返回的JSON不管有没有缩进或换行,jq都能正确解析,不用刻意格式化,保持原始输出即可。
内容的提问来源于stack exchange,提问作者Sourav Chatterjee
相关产品推荐
相关产品推荐

