![用于解析 SNMP 输出的 Bash 脚本](https://linux22.com/image/104157/%E7%94%A8%E4%BA%8E%E8%A7%A3%E6%9E%90%20SNMP%20%E8%BE%93%E5%87%BA%E7%9A%84%20Bash%20%E8%84%9A%E6%9C%AC.png)
我正在监视 Cisco 设备,我需要解析 snmp 输出并将其打印在单独的更详细的行中。
通过命令行我可以这样做:
snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null | awk '{print $4}' | while read -r line ; do echo "Drive $line" ; done
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
Drive online(1)
但是,当我在脚本中使用相同的内容时:
#!/bin/bash
Output=`snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv 10.201.1.131 .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null | awk '{print $4}'`
while read -r line ; do
echo "Drive $line";
done << $Output
我明白了,
bash -x CIMC-Monitong.sh
++ snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my -v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18
++ awk '{print $4}'
+ Output='online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)
online(1)'
CIMC-Monitong.sh: line 9: warning: here-document at line 7 delimited by end-of-file (wanted `$Output')
+ read -r line
+ echo 'Drive '
Drive
+ read -r line
+ echo 'Drive '
Drive
+ read -r line
我缺少什么?
编辑:我没有通过管道传输它的原因是,现在我得到与此类似的输出:
驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1) 驾驶在线(1)在线行驶(1) 在线行驶(1) 在线行驶(1) 在线行驶(1) 在线行驶(1) 在线行驶(1)
但我期望这样的事情:
驱动器1在线(1) 驱动器2在线(1) 驱动器3在线(1) 驱动器4在线(1) 驱动器5在线(1) 驱动器6在线(1) 驱动器7在线(1) 驱动器8在线(1) 驱动器9在线(1) 驱动器10在线(1) Drive11 在线(1) Drive12 在线(1) Drive13 在线(1) Drive14 在线(1) Drive15 在线(1) Drive16 在线(1)
答案1
脚本中的<<$Output
被解释为此处文档的开头。
通常,here-document 会写成,例如,
cat <<END_OF_INPUT
.
.
.
.
END_OF_INPUT
...但是使用$Output
或任何其他字符串作为此处文档分隔符是完全可以的。
您可能打算使用<$Output
,但这也是错误的,因为这会被视为尝试从文件中读取$Output
,该文件不是文件名,而是管道的输出。
尝试将输出通过管道传输到 while 循环,就像在命令行上所做的那样:
#!/bin/bash
snmpwalk -m /usr/share/snmp/mibs/CISCO-UNIFIED-COMPUTING-STORAGE-MIB.my \
-v2c -c opennms-Priv X.X.X.X .1.3.6.1.4.1.9.9.719.1.45.4.1.18 2>/dev/null |
awk '{print $4}' |
while read -r line; do
echo "Drive $line"
done
我倾向于使用printf
而不是echo
当输出需要包含用户提供的数据时(实际上来自脚本外部的任何数据):
printf 'Drive %s\n' "$line"
更新:
如果你的输出需要看起来像
Drive1 online(1)
Drive2 online(1)
... etc.
每行严格加一后的数字Drive
,那么循环中需要一个计数器:
while read -r line; do
printf 'Drive%d %s\n' "$(( ++count ))" "$line"
done