将 snmpbulkwalk 结果放入变量的简单脚本,如何将所有数据放入 2 个数组?
Simple script to put snmpbulkwalk results into variables, how can I put all data in 2 arrays?
我制作了一个简单的脚本来表示仙人掌图,它可以工作,但显然它并没有真正优化,因为我正在使用 snmpbulkwalk 进行 8 次查询并按行号 (FNR==x) 拆分,而我可以只做 2 个查询,使用 2 个数组,一个用于第一个 OID,另一个用于第二个 OID。
我正在自己做这个问题,因为对于 Cacti 来说,脚本越快,Poller 处理数据输入的能力就越好。
#!/bin/bash
#hwCBQoSIfQueueMatchedBytes
qos_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==2 {print }')
qos_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==3 {print }')
qos_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==4 {print }')
#hwCBQoSIfQueueDiscardedBytes
dis_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==2 {print }')
dis_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==3 {print }')
dis_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==4 {print }')
printf "qos_match_2:$qos_match_2 "
printf "qos_match_3:$qos_match_3 "
printf "qos_match_4:$qos_match_4 "
printf "dis_match_2:$dis_match_2 "
printf "dis_match_3:$dis_match_3 "
printf "dis_match_4:$dis_match_4 "
printf "\n"
主机上 'snmpbulkwalk' 命令的示例输出为:
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.1 = Counter64: 0
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.2 = Counter64: 431032480
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.3 = Counter64: 12456864036
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.4 = Counter64: 69821418510
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.5 = Counter64: 0
脚本的示例输出为
qos_match_2:431741706 qos_match_3:12464887554 qos_match_4:69827660661 dis_match_2:0 dis_match_3:345524650 dis_match_4:0
每行对应一个 Qos class,我们只使用 Class 2、3 和 4
OID .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 匹配 QoS 匹配字节和 OID .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6匹配而不是 QoS 丢弃的字节。
我该如何解决这个问题?
在伪代码中我想:
#hwCBQoSIfQueueMatchedBytes
qos_match=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2)
printf "qos_match2:" $qos_match[0]
printf "qos_match3:" $qos_match[1]
printf "qos_match4:" $qos_match[2]
等等
根据 luciole75w 建议更新 07.05.2020:
#!/bin/bash
#set -x
MYCOMMUNITY="mycommunity"
mapfile -t qos_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
awk '2 <= NR && NR <= 4 { print }'
)
mapfile -t dis_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 |
awk '2 <= NR && NR <= 4 { print }'
)
for n in {2..4}; do
printf "qos_match_$n:${qos_match[n-2]} "
done
for n in {2..4}; do
printf "dis_match_$n:${dis_match[n-2]} "
done
printf "\n"
#set +x
要将输出行保存在 bash 数组变量中,您可以使用 mapfile
with a process substitution 作为输入。以下命令应该适合您,请注意我不知道 snmpbulkwalk
所以我只是按原样复制您的命令。
mapfile -t qos_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
awk '2 <= NR && NR <= 4 { print }'
)
for n in {2..4}; do
echo qos_match$n: "${qos_match[n-2]}"
done
如果您的目标实际上是输出字符串(仅)而不是数组,这里有一个替代命令可以在不使用 shell 变量的情况下更有效地获得预期输出。
awk '
2 <= FNR && FNR <= 4 {
printf "%s_match_%d:%s%s", name, FNR, , (++n < 6 ? OFS : ORS)
}
' name=qos <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2
) name=dis <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6
)
我制作了一个简单的脚本来表示仙人掌图,它可以工作,但显然它并没有真正优化,因为我正在使用 snmpbulkwalk 进行 8 次查询并按行号 (FNR==x) 拆分,而我可以只做 2 个查询,使用 2 个数组,一个用于第一个 OID,另一个用于第二个 OID。 我正在自己做这个问题,因为对于 Cacti 来说,脚本越快,Poller 处理数据输入的能力就越好。
#!/bin/bash
#hwCBQoSIfQueueMatchedBytes
qos_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==2 {print }')
qos_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==3 {print }')
qos_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==4 {print }')
#hwCBQoSIfQueueDiscardedBytes
dis_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==2 {print }')
dis_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==3 {print }')
dis_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==4 {print }')
printf "qos_match_2:$qos_match_2 "
printf "qos_match_3:$qos_match_3 "
printf "qos_match_4:$qos_match_4 "
printf "dis_match_2:$dis_match_2 "
printf "dis_match_3:$dis_match_3 "
printf "dis_match_4:$dis_match_4 "
printf "\n"
主机上 'snmpbulkwalk' 命令的示例输出为:
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.1 = Counter64: 0
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.2 = Counter64: 431032480
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.3 = Counter64: 12456864036
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.4 = Counter64: 69821418510
SNMPv2-SMI::enterprises.2011.5.25.32.1.1.5.1.6.1.2.3.2.5 = Counter64: 0
脚本的示例输出为
qos_match_2:431741706 qos_match_3:12464887554 qos_match_4:69827660661 dis_match_2:0 dis_match_3:345524650 dis_match_4:0
每行对应一个 Qos class,我们只使用 Class 2、3 和 4
OID .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 匹配 QoS 匹配字节和 OID .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6匹配而不是 QoS 丢弃的字节。
我该如何解决这个问题?
在伪代码中我想:
#hwCBQoSIfQueueMatchedBytes
qos_match=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2)
printf "qos_match2:" $qos_match[0]
printf "qos_match3:" $qos_match[1]
printf "qos_match4:" $qos_match[2]
等等
根据 luciole75w 建议更新 07.05.2020:
#!/bin/bash
#set -x
MYCOMMUNITY="mycommunity"
mapfile -t qos_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
awk '2 <= NR && NR <= 4 { print }'
)
mapfile -t dis_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 |
awk '2 <= NR && NR <= 4 { print }'
)
for n in {2..4}; do
printf "qos_match_$n:${qos_match[n-2]} "
done
for n in {2..4}; do
printf "dis_match_$n:${dis_match[n-2]} "
done
printf "\n"
#set +x
要将输出行保存在 bash 数组变量中,您可以使用 mapfile
with a process substitution 作为输入。以下命令应该适合您,请注意我不知道 snmpbulkwalk
所以我只是按原样复制您的命令。
mapfile -t qos_match < <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
awk '2 <= NR && NR <= 4 { print }'
)
for n in {2..4}; do
echo qos_match$n: "${qos_match[n-2]}"
done
如果您的目标实际上是输出字符串(仅)而不是数组,这里有一个替代命令可以在不使用 shell 变量的情况下更有效地获得预期输出。
awk '
2 <= FNR && FNR <= 4 {
printf "%s_match_%d:%s%s", name, FNR, , (++n < 6 ? OFS : ORS)
}
' name=qos <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2
) name=dis <(
snmpbulkwalk -v 2c -c $MYCOMMUNITY .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6
)