genx1mx6
genx1mx6

Reputation: 453

how does exp_continue work? Issues with exp_continue

I'm trying to capture the inventory data off my cisco equipment. I though it would be pretty easy but I'm having issues.

instead of matching and entire "set" of data (from Name.+SN is one set) I thought I'd split my maches up and use exp_continue to make my Regex more readable.

If you look below, it seems exp_continue is being super greedy when it gathers the "name"

data set:

HOSTNAME#sho inventory
NAME: "WS-C6506-E", DESCR: "Cisco Systems, Inc. Catalyst 6500 6-slot Chassis System"
PID: WS-C6506-E        ,                     VID: V03, SN: SAL1547VW8B

NAME: "WS-C6K-VTT-E 1", DESCR: "VTT-E FRU 1"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B899

NAME: "WS-C6K-VTT-E 2", DESCR: "VTT-E FRU 2"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B910

NAME: "WS-C6K-VTT-E 3", DESCR: "VTT-E FRU 3"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B903

NAME: "CLK-7600 1", DESCR: "OSR-7600 Clock FRU 1"
PID: CLK-7600          ,                     VID:    , SN: SMT1544A575

NAME: "CLK-7600 2", DESCR: "OSR-7600 Clock FRU 2"
PID: CLK-7600          ,                     VID:    , SN: SMT1544A575

NAME: "3", DESCR: "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1"
PID: WS-X6724-SFP      ,                     VID: V08, SN: SAL160214AY

NAME: "WS-F6700-CFC Centralized Forwarding Card sub-module of 3", DESCR: "WS-F6700-CFC Centralized Forwarding Card Rev. 4.1"
PID: WS-F6700-CFC      ,                     VID: V06, SN: SAL160317SU

NAME: "4", DESCR: "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6"
PID: WS-X6324-100FX-MM ,                     VID:    , SN: SAL091805J9

NAME: "5", DESCR: "WS-SUP720-3B 2 ports Supervisor Engine 720 Rev. 5.6"
PID: WS-SUP720-3B      ,                     VID: V05, SN: SAL1226UYLK

NAME: "msfc sub-module of 5", DESCR: "WS-SUP720 MSFC3 Daughterboard Rev. 3.1"
PID: WS-SUP720         ,                     VID:    , SN: SAL1226UXVD

NAME: "WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5", DESCR: "WS-F6K-PFC3B Policy Feature Card 3 Rev. 2.3"
PID: WS-F6K-PFC3B      ,                     VID: V01, SN: SAL1225UQAQ

NAME: "6", DESCR: "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6"
PID: WS-X6324-100FX-MM ,                     VID:    , SN: SAL091805HU

NAME: "WS-C6506-E-FAN 1", DESCR: "Enhanced 6-slot Fan Tray 1"
PID: WS-C6506-E-FAN    ,                     VID: V03, SN: DCH1547004V

NAME: "PS 1 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 1"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX19

NAME: "PS 2 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 2"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX1F
HOSTNAME#

code:

send "show inventory\r"
expect {
        -nocase -re {NAME: "([^\"]+)"} {
                set NAME $expect_out(1,string)
                puts "Name $NAME!!!!"
                exp_continue
        }
        -nocase -re {DESCR: "([^\"]+)"} {
                set DESCR $expect_out(1,string)
                puts "Des $DESCR!!!!"
                exp_continue
        }
        -nocase -re {PID:([^,]+)} {
                set PID $expect_out(1,string)
                puts "PID $PID!!!!"
                exp_continue
        }
        -nocase -re {VID:([^,]+)} {
                set VID $expect_out(1,string)
                puts "VID $VID!!!!"
                exp_continue
        }
        -nocase -re {SN: ([^\r]+)} {
                set SN $expect_out(1,string)
                puts "SN $SN!!!!\n\n"
                lappend info "$hostname,$NAME,$DESCR,$PID,$VID,$SN"
                exp_continue
        }
        "#"
}
 foreach I $info {
   puts "$I"
  }

And here is the output

Name WS-C6506-E!!!!
Name WS-C6K-VTT-E 1!!!!
Name WS-C6K-VTT-E 2!!!!
Name WS-C6K-VTT-E 3!!!!
Name CLK-7600 1!!!!
Name CLK-7600 2!!!!
Name 3!!!!
Name WS-F6700-CFC Centralized Forwarding Card sub-module of 3!!!!
Name 4!!!!
Name 5!!!!
Name msfc sub-module of 5!!!!
Name WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5!!!!
Name 6!!!!
Name WS-C6506-E-FAN 1!!!!
Name PS 1 WS-CAC-3000W!!!!
Name PS 2 WS-CAC-3000W!!!!
Des AC power supply, 3000 watt 2!!!!
PID  WS-CAC-3000W      !!!!
VID  V02!!!!
SN SNI1543AX1F!!!!

HOSTNAME,AC power supply, 3000 watt 2, WS-CAC-3000W      , V02,SNI1543AX1F

Upvotes: 0

Views: 2248

Answers (2)

pynexj
pynexj

Reputation: 20797

You should include all the keywords (NAME, DESCR, ...) in one single regular expression. For example:

$ cat foo.exp
log_user 0
spawn cat file
set info {}
expect {
    -re {NAME: "([^"]*)",\s*DESCR: "([^"]*)"\s+PID: (\S*)\s*,\s*VID:\
         (\S*)\s*,\s*SN: (\S*)} {
        set name $expect_out(1,string)
        set desc $expect_out(2,string)
        set pid  $expect_out(3,string)
        set vid  $expect_out(4,string)
        set sn   $expect_out(5,string)
        lappend info "$name | $desc | $pid | $vid | $sn"
        exp_continue
    }
}

foreach i $info {
    puts $i
}
$ cat file
NAME: "WS-C6K-VTT-E 1", DESCR: "VTT-E FRU 1"
PID: WS-C6K-VTT-E      ,                     VID:    , SN: SMT1541B899

NAME: "3", DESCR: "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1"
PID: WS-X6724-SFP      ,                     VID: V08, SN: SAL160214AY

NAME: "PS 2 WS-CAC-3000W", DESCR: "AC power supply, 3000 watt 2"
PID: WS-CAC-3000W      ,                     VID: V02, SN: SNI1543AX1F
$ expect foo.exp
WS-C6K-VTT-E 1 | VTT-E FRU 1 | WS-C6K-VTT-E |  | SMT1541B899
3 | WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1 | WS-X6724-SFP | V08 | SAL160214AY
PS 2 WS-CAC-3000W | AC power supply, 3000 watt 2 | WS-CAC-3000W | V02 | SNI1543AX1F
$

Upvotes: 1

Dinesh
Dinesh

Reputation: 16436

Since the NAME match is always checked at first, you tend to see this behavior due to exp_continue which is misused here.

Instead of this, you can wait till the prompt of the your device. The whole output will be available in the expect_out(buffer). Then apply the regexp to extract the required data.

send "show inventory\r"
expect "HOSTNAME#"
set cmdResponse $expect_out(buffer); # Saving the buffer output to another variable
# 'inline' and 'all' flags will cause the all matches to be returned as list
set resultList [regexp -inline -all {NAME.*?"([^"]+)?.*?DESCR.*?"([^"]+)?.*?PID.*?\s(\S+).*?,.*?VID:\s+(.*)?,.*?SN:\s(.*)?\n} $cmdResponse ]

# Quoting the values with double quotes
foreach {whole_match name descr pid vid serialno} $resultList {
        puts "NAME = \"$name\", DESCR = \"$descr\", PID = \"$pid\", VID = \"$vid\", SN = \"$serialno\""
}

Output :

NAME = "WS-C6506-E", DESCR = "Cisco Systems, Inc. Catalyst 6500 6-slot Chassis System", PID = "WS-C6506-E", VID = "V03", SN = "SAL1547VW8B"
NAME = "WS-C6K-VTT-E 1", DESCR = "VTT-E FRU 1", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B899"
NAME = "WS-C6K-VTT-E 2", DESCR = "VTT-E FRU 2", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B910"
NAME = "WS-C6K-VTT-E 3", DESCR = "VTT-E FRU 3", PID = "WS-C6K-VTT-E", VID = "", SN = "SMT1541B903"
NAME = "CLK-7600 1", DESCR = "OSR-7600 Clock FRU 1", PID = "CLK-7600", VID = "", SN = "SMT1544A575"
NAME = "CLK-7600 2", DESCR = "OSR-7600 Clock FRU 2", PID = "CLK-7600", VID = "", SN = "SMT1544A575"
NAME = "3", DESCR = "WS-X6724-SFP CEF720 24 port 1000mb SFP Rev. 5.1", PID = "WS-X6724-SFP", VID = "V08", SN = "SAL160214AY"
NAME = "WS-F6700-CFC Centralized Forwarding Card sub-module of 3", DESCR = "WS-F6700-CFC Centralized Forwarding Card Rev. 4.1", PID = "WS-F6700-CFC", VID = "V06", SN = "SAL160317SU"
NAME = "4", DESCR = "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6", PID = "WS-X6324-100FX-MM", VID = "", SN = "SAL091805J9"
NAME = "5", DESCR = "WS-SUP720-3B 2 ports Supervisor Engine 720 Rev. 5.6", PID = "WS-SUP720-3B", VID = "V05", SN = "SAL1226UYLK"
NAME = "msfc sub-module of 5", DESCR = "WS-SUP720 MSFC3 Daughterboard Rev. 3.1", PID = "WS-SUP720", VID = "", SN = "SAL1226UXVD"
NAME = "WS-F6K-PFC3B Policy Feature Card 3 sub-module of 5", DESCR = "WS-F6K-PFC3B Policy Feature Card 3 Rev. 2.3", PID = "WS-F6K-PFC3B", VID = "V01", SN = "SAL1225UQAQ"
NAME = "6", DESCR = "WS-X6324-100FX-MM 24 port 100FX Multi mode Rev. 3.6", PID = "WS-X6324-100FX-MM", VID = "", SN = "SAL091805HU"
NAME = "WS-C6506-E-FAN 1", DESCR = "Enhanced 6-slot Fan Tray 1", PID = "WS-C6506-E-FAN", VID = "V03", SN = "DCH1547004V"
NAME = "PS 1 WS-CAC-3000W", DESCR = "AC power supply, 3000 watt 1", PID = "WS-CAC-3000W", VID = "V02", SN = "SNI1543AX19"
NAME = "PS 2 WS-CAC-3000W", DESCR = "AC power supply, 3000 watt 2", PID = "WS-CAC-3000W", VID = "V02", SN = "SNI1543AX1F"

There are some entries which doesn't have VID info, will be displayed as empty string in the output as well.

Upvotes: 2

Related Questions