【问题标题】:Simple script to put snmpbulkwalk results into variables, how can I put all data in 2 arrays?将 snmpbulkwalk 结果放入变量的简单脚本,如何将所有数据放入 2 个数组中?
【发布时间】:2020-05-06 13:56:00
【问题描述】:

我制作了一个简单的脚本来表示仙人掌图,它可以工作,但显然它并没有真正优化,因为我正在使用 snmpbulkwalk 进行 8 次查询并按行号 (FNR==x) 分割,而我本来可以只完成了 2 个查询,使用 2 个数组,一个用于第一个 OID,另一个用于第二个 OID。 我正在为自己做这个问题,因为显然对于 Cacti 来说,脚本越快,轮询器处理数据输入的能力就越好。

#!/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 建议之后更新 07.05.2020:

#!/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

【问题讨论】:

  • 旁注:printf 应使用包含格式说明符(%s%d...)和可变部分作为参数的格式字符串调用。如果你将 shell 变量直接放在格式字符串中,其中一些扩展为包含% 或转义序列的字符串,那么它会打印错误,或者只是失败。
  • 感谢提醒,是的,我一直在以不正确的方式使用“printf”,只是为了避免最后出现“echo”换行符。显然,我本可以做不同的。
  • 有关信息,在大多数 shell 中,echo 还支持 -n 选项以跳过换行符。

标签: bash awk snmp cacti


【解决方案1】:

要将输出行保存在 bash 数组变量中,您可以使用 mapfileprocess substitution 作为输入。下面的命令应该对你有用,注意我不知道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
)

【讨论】:

  • 谢谢,我根据我的情况调整了你的工作,它有效!我不知道'mapfile'功能,我肯定会花很多时间才能找到该功能:)
  • 看你的更新,不知道你添加的bash脚本是完整的还是只是你处理的一部分。如果您真的想将结果存储在 shell 数组中,按照标题,以便在输出字符串之后进行进一步处理,那么 mapfile 就是您所需要的。但如果输出字符串是您的最终目的,那么您不需要 shell 变量,awk 可以轻松完成这项工作。请参阅我的更新答案。
  • 您好,感谢您的反馈。抱歉,我工作比较忙,没时间分析你的更新。我会尽快看看。顺便说一句,谢谢你的时间:)
  • 顺便说一句,我有几分钟的时间来测试你是否使用 awk,它的工作原理是一样的。我相信我会保留 bash 数组,因为它对我来说更清楚。我一直在使用 AWK 时遇到问题,更少使用 bash 语法。我唯一的目标是保持脚本的时间较短(使用 bash 中的“时间”命令测量),因为它对于 Cacti 网络监视器来说较轻。我考虑过使用数组,因为它是我想到的第一个数据结构,可以在不执行 3 次相同查询的情况下保持数据索引。我尝试使用 AWK,但显然我做错了什么,我离你的例子很远。
  • 不客气。 awk 是一个强大的多功能工具,我认为值得花一些时间来了解主要功能,它迟早会有所收获。当您决定使用 awk 之类的工具时,我认为最好看看它如何让您的整个任务变得更轻松,而不是只挑选一小部分并与其他工具混合使用。
猜你喜欢
  • 2015-11-17
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 2020-07-25
  • 2018-12-03
相关资源
最近更新 更多