Bash隔离结果

时间:2017-01-05 14:29:12

标签: regex linux bash grep

我从bash开始,我想实现一个检查命令ibstat上的数据的脚本 Ibstat以此为例返回:

command ibstat
Ibstat returns this for example:

# ibstat
CA 'mlx4_0'
        CA type: MT25418
        Number of ports: 2
        Firmware version: 2.3.0
        Hardware version: a0
        Node GUID: 0x0002c9030002fb04
        System image GUID: 0x0002c9030002fb07
        Port 1:
                State: Active
                Physical state: LinkUp
                Rate: 20
                Base lid: 2
                LMC: 0
                SM lid: 1
                Capability mask: 0x02510868
                Port GUID: 0x0002c9030002fb05
        Port 2:
                State: Down
                Physical state: Polling
                Rate: 10
                Base lid: 0
                LMC: 0
                SM lid: 0
                Capability mask: 0x02510868
                Port GUID: 0x0002c9030002fb06

我希望每个端口检查物理状态:是否等于LinkUp,否则我返回错误。 我使用grep和awq来隔离第一个物理状态,但是我们如何使用一种for循环来检查每个“节点”端口?

这是我的实际代码:

ibstat | grep "Physical state" | awk '{ print $3 }'

我想分隔端口号(in或while?)

对于输出结果,我想要一条错误消息,如: “错误端口2不是链接”

1 个答案:

答案 0 :(得分:1)

更新了答案

由于awk不再可接受(!),因此这是bash版本:

ibstat | while IFS=':' read f1 f2; do
   # If first field is "Port", remember port in variable $p
   [[ $f1 =~ .*Port.* ]] && p="$f1"
   # If first field is "Physical state"
   if [[ "$f1" =~ "Physical state" ]]; then
      # Just carry on if second field is "LinkUp"
      [[ $f2 =~ "LinkUp" ]] && continue
      echo "ERROR: $p is not LinkUp ($f2)"
   fi
done

显然你会像这样放入一个名为CheckLink的脚本:

#!/bin/bash
while IFS=':' read f1 f2; do
   # If first field is "Port", remember port in variable $p
   [[ $f1 =~ .*Port.* ]] && p="$f1"
   # If first field is "Physical state"
   if [[ "$f1" =~ "Physical state" ]]; then
      # Just carry on if second field is "LinkUp"
      [[ $f2 =~ "LinkUp" ]] && continue
      echo "ERROR: $p is not LinkUp ($f2)"
   fi
done

并使用以下命令使其可执行:

chmod +x CheckLink

然后用

运行它
ibstat | ./CheckLink

示例输出

ERROR:         Port 2 is not LinkUp ( Polling)

原始答案

这个怎么样:

ibstat | awk -F: '$1~/Port [0-9]+/{p=$1} /Physical state:/ && ! /LinkUp/{print p,$2}'

示例输出

Port 2  Polling

因此,每当我们看到Port后面跟一个空格和一些数字时,我们就会记住变量p中的端口。每当我们在同一行上看到Physical state:但不在LinkUp时,我们会打印保存的端口号和第二个字段。

或者,如果您想要快速,简单和简单,您可以只查看所有端口和所有物理状态:

ibstat | grep -E "Port \d+:|Physical state:"

示例输出

    Port 1:
            Physical state: LinkUp
    Port 2:
            Physical state: Polling