user7379681
user7379681

Reputation: 53

Bash isolate result

I start in bash and I would like to realize a script that checks the data on the command ibstat Ibstat returns this for example:

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

I would like for each port to check that Physical state: is equal to LinkUp otherwise I return an error. I arrive with grep and awq to isolate the 1st Physical state, but how do we make a kind of for loop to check each "node" port?

this is my actual code:

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

i want to separate Port number (in for or while ?)

For output result i want a error message like : "Error port 2 is not linkup"

Upvotes: 0

Views: 189

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207465

Updated Answer

As awk is no longer acceptable (!), here is a bash version:

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

Obviously you would put in a script, called CheckLink like this:

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

and make it executable with:

chmod +x CheckLink

and then run it with

ibstat | ./CheckLink

Sample Output

ERROR:         Port 2 is not LinkUp ( Polling)

Original Answer

How about this:

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

Sample Output

Port 2  Polling

So, every time we see Port followed by a space and some digits, we remember the port in variable p. Every time we see Physical state: but not with LinkUp on the same line, we print the port number we saved and the second field on the line.


Or, if you want quick, dirty and simple, you could just grep all the Ports and all the Physical states:

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

Sample Output

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

Upvotes: 1

Related Questions