如何将变量传入JQ,从AWS ELB输出中筛选安全组?
问题描述
现有可用的AWS CLI命令可查询指定负载均衡器的安全组:
aws elb describe-load-balancers |\ jq '.LoadBalancerDescriptions[] |\ select(.DNSName == "internal-elbdnsendpoint1.us-east-1.elb.amazonaws.com") |\ .LoadBalancerName, .SecurityGroups[]'
我想获取所有已部署服务(负载均衡器)的安全组,编写了如下循环命令但无法正常工作:
for i in `kubectl get svc -A | grep LoadB | awk '{print $5}'`; do\ aws elb describe-load-balancers |\ jq -r --arg var $i '.LoadBalancerDescriptions[] | select(.DNSName == $var) | ...';\ done
我尝试过使用"$var"、$var和[$var],但select(.DNSName == $var)始终无法生效。不过我的测试命令可以正常运行:
echo '{"vikas": [{"k2": "v1"},{"k2":"v2","k3":"v3"}]}' |\ jq -r --arg var "$i" '.vikas[] | select(.k2 == "v2") | .k2, .k3'
负载均衡器DNS示例输出:
internal-elbdnsendpoint1.us-east-1.elb.amazonaws.com internal-elbdnsendpoint2.us-east-1.elb.amazonaws.com internal-elbdnsendpoint3.us-east-1.elb.amazonaws.com internal-elbdnsendpoint4.us-east-1.elb.amazonaws.com
请求提供正确的命令,并解释该问题的原因。
正确命令
基础版本(逐次调用AWS API)
kubectl get svc -A | grep LoadB | awk '{print $5}' | while read -r lb_dns; do aws elb describe-load-balancers | jq -r --arg dns "$lb_dns" '.LoadBalancerDescriptions[] | select(.DNSName == $dns) | .LoadBalancerName, .SecurityGroups[]' done
高效版本(仅调用一次AWS API)
如果负载均衡器数量较多,建议先一次性获取所有负载均衡器数据,再循环匹配,减少API调用次数:
# 先拉取所有负载均衡器数据到变量 LB_DATA=$(aws elb describe-load-balancers) # 逐行读取DNS并匹配 kubectl get svc -A | grep LoadB | awk '{print $5}' | while read -r lb_dns; do echo "$LB_DATA" | jq -r --arg dns "$lb_dns" '.LoadBalancerDescriptions[] | select(.DNSName == $dns) | .LoadBalancerName, .SecurityGroups[]' done
问题原因
- 变量传递的引号缺失:原命令中
--arg var $i没有给$i添加双引号,当DNS字符串包含特殊字符(或输出中存在隐性空格)时,Shell会将变量内容拆分,导致jq接收到的参数不完整。必须用--arg dns "$lb_dns"把变量包裹在双引号里,确保DNS字符串完整传递给jq。 - for循环的输出拆分问题:
for i inkubectl ...``这种写法会把命令输出按空格、换行符等空白字符拆分,一旦kubectl输出的DNS中存在空格(哪怕是隐性的),循环变量就会被错误分割。改用while read -r lb_dns可以逐行读取输出,保证每个DNS作为独立的完整变量值被处理。 - jq变量引用的误区:通过
--arg传入jq的变量直接用$变量名引用即可,不需要额外加引号或方括号。你之前的测试命令用的是硬编码值"v2",而实际场景只要变量传递正确,select(.DNSName == $dns)就能正常匹配。
内容的提问来源于stack exchange,提问作者user2534033
相关产品推荐
相关产品推荐

