【发布时间】:2021-03-04 08:14:18
【问题描述】:
我正在为我的 openwrt 编写脚本,它是我的 pia 连接的看门狗。我正在尝试制作这个小 jq 过滤器,但每次尝试时都会出错 我有更多选择,我“编写”了 jq 过滤器
all_region_data=$(curl -s "https://serverlist.piaservers.net/vpninfo/servers/v4" | head -1)
BestRegion="italy"
jq_filter='.regions[]'
if [ -z "$BestRegion" ]; then # BestRegion not forced
if [ "$pia_pf" = "true" ]; then
jq_filter="${jq_filter} | select(.port_forward==true)"
fi
if [ "$pia_no_geo" = "false" ]; then
jq_filter="${jq_filter} | select(.geo==false)"
fi
if [ "$pia_no_geo" = "true" ]; then
jq_filter="${jq_filter} | select(.geo==true)"
fi
jq_filter="${jq_filter} | .servers.meta[0].ip+\" \"+.id+\" \"+.name+\" \"+(.geo|tostring)"
summarized_region_data=$(echo "$all_region_data" | jq -r "${jq_filter}")
best_region # function to extract best_region
if [ -z "$BestRegion" ]; then
log "..."
log "No region responded within ${max_latency}s, consider using a higher timeout."
rm -rf "$wg_script_lock_file"
return
fi
else # BestRegion forced
if [ "$pia_pf" = "true" ]; then
jq_filter="${jq_filter} | select(.port_forward==true)"
fi
if [ "$pia_no_geo" = "false" ]; then
jq_filter="${jq_filter} | select(.geo==false)"
fi
if [ "$pia_no_geo" = "true" ]; then
jq_filter="${jq_filter} | select(.geo==true)"
fi
fi
第一个if cycle 工作,函数做脏工作。但我想有机会“强制”BestRegion,所以我创建了else cycle。问题来了!
这就是我想要做的事情
echo $all_region_data | jq --arg REGION_ID "$BestRegion" --arg JQ_FILTER "$jq_filter" -r '$JQ_FILTER | select(.id==$REGION_ID)'
我不能使用这两个var,我得到这个错误
jq: error (at <stdin>:1): Cannot index string with string "id"
你会怎么做?
【问题讨论】:
-
调用
jq --arg REGION_ID "$BestRegion" --arg JQ_FILTER "$jq_filter" -r $JQ_FILTER | select(.id==$REGION_ID)'相当混乱。密切注意shell变量和jq变量的区别。并且不要忘记,如果您在 shell 中设置 X=.a,那么jq --arg x "$X" '$x'将打印 JSON 字符串".a" -
我可以对变量重新排序,以便将第一个
arg设置为 jq_filter,第二个设置为 region_id。我还可以更改 var 名称以确保不会犯任何错误。如果我只使用一个arg但我需要两个,那么一切正常。我需要一个非 JSON 输出,所以我在 jq 中使用了-r选项,我认为是对的。我认为问题出在"和'上,但我不知道如何处理,我尝试了很多变体但没有运气