我正在编写一个shell脚本来解析ethtool
命令中的advertised mode和supported mode,并将它们与预期值进行匹配。
数据来源:
# ethtool eth5
Settings for eth1:
Supported ports: [ Backplane ]
Supported link modes: 1000baseKX/Full
10000baseKR/Full
15000baseKR/Full
Supported pause frame use: Symmetric
Supports auto-negotiation: Yes
Supported FEC modes: None BaseR RS
Advertised link modes: 1000baseKX/Full
10000baseKR/Full
15000baseKR/Full
我目前使用下面的相同。
link_mode_expected=15000baseKR
# get the mode using the shell command and parse the value needed
mode_supported=`ethtool ${eth_device} | sed -ne '/Supported link modes:/,/:/p' |\
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep "$link_mode_expected"`
mode_advertised=`ethtool ${eth_device} | sed -ne '/Advertised link modes:/,/:/p' |\
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep "$link_mode_expected"`
if [ "$mode_supported" != "$link_mode_expected" ] ||\
( [ "$mode_supported" != "$mode_advertised" ] ) ; then
#some action
fi
以上代码给出了正确的结果,即mode_advertised
和mode_supported
的结果均为15000 baseKR/Full,我正在执行上述逻辑,但我希望获得以下帮助
1.如何避免两个ethtool
命令,我们是否可以将输出添加到缓冲区并从该缓冲区添加grep?
1.如果awk的执行速度更快,那么awk的等价物是什么?
1.有没有比以上更好的方法?
1条答案
按热度按时间3htmauhk1#
Awk确实会是你在这里所有问题的答案。
演示,带一些调试打印:https://ideone.com/v5du8g
让Awk执行比较并设置
if
的退出状态以进行检查在Awk方面有点笨拙,但这使得该脚本非常容易和自然地从周围的shell脚本中使用。与
sed
一样,Awk处理一行在这个脚本中,简单的变量s
和a
反映了当前输入行是否在一个区域中,该区域分别枚举了支持的模式或通告的模式。如果我们在这样的区域中,我们检查该行的最后一个字段($NF
)以数值方式计算(+ 0
)到lme
中的数字。在这种情况下,Awk很方便地忽略了值的任何非数字尾部。在结尾,我们将退出状态设置为0表示成功(两个值都找到了),否则设置为1,这与shell的约定一致(零退出代码表示成功,其他任何值都表示失败)。作为一种替代方法,您可以尝试找出一个记录分隔符(
RS
)来进行拆分,而不是换行。在冒号上拆分可能是好的,因为这样您就可以一次检查整个区域(但是这样您就失去了NF
包含您要检查的字段的索引的简单而优雅的特性,所以最终可能一点也不简单)。您也可以选择让Awk提取并打印这些值,然后在shell中进行比较;但是让shell解析刚刚花了大量时间解析的Awk的输出是呆板和不吸引人的。
这个脚本并不完全是琐碎的,但是你会发现学习足够多的Awk来编写更简单的脚本是非常愉快和快速的,非常值得你花时间。你可以在30分钟到1小时的预算内完成相当多的工作。
需要自定义解析器的特殊输出格式是一个不断的挫折和摩擦的来源。越来越多的现代工具可以选择以正确的机器可读的标准格式(如JSON、YAML或XML)生成输出。遗憾的是,
ethtool
似乎没有任何这样的功能。