简单的脚本把snmpbulkwalk的结果放到变量中,如何把所有数据放到2个数组中?

问题描述 投票:0回答:1

我做了一个简单的脚本来表示Cacti Graph,它可以工作,但是很明显它并没有真正的优化,因为我用snmpbulkwalk做了8个查询,并且按行号分割(FNR==x),而我可以只做2个查询,使用2个数组,一个用于第一个OID,另一个用于第二个OID.我自己做这个问题,因为很明显对于Cacti来说,脚本的速度越快,Poller可以更好的处理数据输入。

#!/bin/bash
#hwCBQoSIfQueueMatchedBytes
qos_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==2 {print $4}')
qos_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==3 {print $4}')
qos_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 | awk 'FNR==4 {print $4}')
#hwCBQoSIfQueueDiscardedBytes
dis_match_2=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==2 {print $4}')
dis_match_3=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==3 {print $4}')
dis_match_4=$(snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 | awk 'FNR==4 {print $4}')

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类,我们只用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 .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的建议,更新2020年5月7日。

#!/bin/bash

#set -x

MYCOMMUNITY="mycommunity"

mapfile -t qos_match < <(
    snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
    awk '2 <= NR && NR <= 4 { print $4 }'
)

mapfile -t dis_match < <(
    snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6 |
    awk '2 <= NR && NR <= 4 { print $4 }'
)

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 awk snmp cacti
1个回答
0
投票

要将输出行保存在bash数组变量中,你可以使用 mapfile 附带 工艺替代 作为输入。下面的命令对你来说应该是有效的,注意到我不知道 snmpbulkwalk 所以我只是把你的命令原封不动地复制过来。

mapfile -t qos_match < <(
    snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.2 |
    awk '2 <= NR && NR <= 4 { print $4 }'
)

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, $4, (++n < 6 ? OFS : ORS)
    }
' name=qos <(
    snmpbulkwalk -v 2c -c $MYCOMMUNITY $1 .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 .1.3.6.1.4.1.2011.5.25.32.1.1.5.1.6.1.6
)
© www.soinside.com 2019 - 2024. All rights reserved.