Shell脚本中变量替换失效问题求助
问题:Shell脚本中jq解析结果无法正确赋值给变量
直接执行jq命令能得到正确结果1,但将结果赋值给变量时出现异常:
COUNT输出为空COUNT_1执行时报command not found错误
原脚本
#! /bin/sh cat sample.json | jq '. | select(.type=="Point" and .metric=="iterations") | .data.value' | jq -s add COUNT=`cat sample.json` | jq '. | select(.type=="Point" and .metric=="iterations") | .data.value' | jq -s add echo "Value of Count: $Count" TOTAL=$(cat sample.json) COUNT_1=`$TOTAL | jq '. | select(.type=="Point" and .metric=="iterations") |.data.value' | jq -s add` echo "Value of Count_1: $Count_1"
执行输出
1 null Value of Count: test.sh: line 13: {"type":"Metric","data":{"name":"http_reqs","type":"counter","contains":"default","thresholds":[],"submetrics":null},"metric":"http_reqs"}: command not found Value of Count_1:
错误原因分析
COUNT变量赋值错误:
- 反引号仅包裹了
cat sample.json,导致cat的输出被当作管道前的命令执行,而非作为jq的输入。正确做法是将整个管道命令放在赋值符号的括号/反引号内。 - 变量名大小写不一致:赋值用
COUNT,但echo时用了$Count,Shell变量区分大小写,因此输出为空。
- 反引号仅包裹了
COUNT_1变量赋值错误:
$TOTAL展开后是sample.json的JSON内容,Shell会将这些内容当作命令执行,必然触发command not found错误。正确做法是将变量内容通过echo传给jq,而非直接展开执行。
修正后的脚本
#! /bin/sh # 保留原验证命令 cat sample.json | jq '. | select(.type=="Point" and .metric=="iterations") | .data.value' | jq -s add # 修正COUNT赋值:将整个管道命令放入$(),统一变量名大小写 COUNT=$(cat sample.json | jq '. | select(.type=="Point" and .metric=="iterations") | .data.value' | jq -s add) echo "Value of Count: $COUNT" # 优化写法:合并两次jq调用,直接让jq读取文件 COUNT_1=$(jq -s '[.[] | select(.type=="Point" and .metric=="iterations") | .data.value] | add' sample.json) echo "Value of Count_1: $COUNT_1"
关键优化点
- 用
$()代替反引号,可读性更强且支持嵌套。 - 合并两次jq调用为一次:通过
-s(--slurp)将所有JSON对象读入数组,筛选后直接求和,减少进程开销。 - 直接让jq读取文件(
jq ... sample.json),避免多余的cat管道(无意义的cat调用)。
内容的提问来源于stack exchange,提问作者Starbucks Admin
相关产品推荐
相关产品推荐

