03-16-2021 04:04 AM
Hi, does anyone have an example of how to select some data in expect via regexp and write it to a variable so that it can be used later?
show run | inc hostname hostname test-gw
sh ip int br | i Vlan9 Vlan9 192.168.100.200 YES NVRAM up up
i wrote code like this
expect -exact "#" {send -- "show run | inc hostname\n"} regexp {hostname ([\_A-Za-z0-9]+)} $expect_out(buffer) matched name expect -exact "#" {puts "Hostname: $name"} expect -exact "#" {send -- "sh ip int br | i Vlan9\r"} regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $expect_out(buffer) matched ip_src expect -exact "#" {send -- "ping $ip_src"}
but he doesn't want to work
03-16-2021 04:16 AM
it does not work too
expect -exact "#" {send -- "show run | inc hostname\n"} regexp {!?gw} $expect_out(buffer) matched name expect -exact "#" {puts "name: $name"}
03-16-2021 08:19 AM - edited 03-16-2021 08:23 AM
This works.
#!/usr/bin/expect set timeout -1 spawn $env(SHELL) match_max 100000 send -- "ssh admin@192.168.0.241\r" expect -exact "Password: " send -- "admin\r" expect -exact "#" send -- "show run | inc hostname\r" set myhost [string trim $expect_out(buffer)] puts "My hostname is $myhost"
# Run script [dafrey@CrashCart biz]$ ./exprouter.tcl spawn /bin/bash ssh admin@192.168.0.241 [dafrey@CrashCart biz]$ ssh admin@192.168.0.241 Password: lab-csr7#My hostname is lab-csr7# [dafrey@CrashCart biz]$
03-16-2021 08:27 AM
hi, yes, this is how I tried it, but here's what to do if we only need "csr7"
03-16-2021 09:09 AM
OK. The match takes place after the dash.
#!/usr/bin/expect set timeout -1 spawn $env(SHELL) match_max 100000 send -- "ssh admin@192.168.0.241\r" expect -exact "Password: " send -- "admin\r" expect -exact "#" send -- "show run | inc hostname\r" set myhost [string trim $expect_out(buffer)] regexp {\-([\_A-Za-z0-9]+)} $myhost match name puts "My hostname is $name"
03-16-2021 09:51 AM
hm, I’m starting to understand, but if there is no task to cut the string?
let's say we execute "sh ip int br | inc vla10"
and in it regexp "\ d + \. \ d + \. \ d + \. \ d +" will work? I haven’t gotten to the pc yet to test it myself
03-16-2021 10:13 AM
Find out what the output looks like without any regexp, then add in regexp and test again. The easiest way to do this is with the interactive tcl shell in IOS. tcl and expect are very similar.
C3750X-G#tclsh C3750X-G(tcl)#set result [exec show ip int brief | inc Vlan11] Vlan11 192.168.223.1 YES NVRAM up up C3750X-G(tcl)#regexp {(\d+.\d+.\d+.\d+)} $result match v11 1 C3750X-G(tcl)#puts $v11 192.168.223.1
03-16-2021 10:20 AM - edited 03-16-2021 10:26 AM
something is wrong, in tcl I checked it works there, in eem, it works, but expect resists
it work
expect -exact "#" send -- "sh run | i hostname\r" set name $expect_out(buffer) regexp {([\_A-Za-z0-9]+)} $name match hostname puts "$hostname"
test-gw#show run | inc hostname
hostname test-gw
./ssh 192.168.18.200
spawn ssh -o StrictHostKeyChecking=no test@192.168.18.200
Password:
test-gw#test
it doesn't work.....
expect -exact "#" send -- "sh ip int br | i Vlan9\r" set src $expect_out(buffer) regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $src match ipsrc puts "ADDRESS: $ipsrc"
test-gw#sh ip int br | i Vlan9
Vlan9 192.168.18.200 YES NVRAM up up
./ssh 192.168.18.200
spawn ssh -o StrictHostKeyChecking=no test@192.168.18.200
Password:
test-gw#can't read "ipsrc": no such variable
while executing
"puts "ADDRESS: $ipsrc""
(file "./ssh" line 26)
03-16-2021 11:16 AM
Looks like your device is not doing regexp to make variable ipsrp because src variable is not present. Most likely it is not running the "show ip int brief | inc vlanxx" command. Some tweaks below.
expect -exact "#" send -- "show ip int brief | inc Vlan11 \r" expect -exact "#" set v11 $expect_out(buffer) regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $v11 match srcip puts " ADDRESS: $srcip" [root@CrashCart biz]# ./exprouter.tcl spawn /bin/bash ssh dafrey@192.168.0.2 [root@CrashCart biz]# ssh dafrey@192.168.0.2 Password: C3750X-G#show ip int brief | inc Vlan11 Vlan11 192.168.223.1 YES NVRAM up up C3750X-G# ADDRESS: 192.168.223.1
03-16-2021 06:27 PM
very strange, because I took the commands directly from the eem script on the same router, I'm now trying to make an out-of-the-box check of the router
03-16-2021 07:24 PM
Apparently after executing the command "show ip int br | inc Vlan9" there is a delay, the variable has not yet been created, and regexp is trying to perform the next action, added after "show ip int br | inc Vlan9" a string to expect the character "expect -exact" # "" and it worked
expect -exact "#" send -- "sh ip int br | i Vlan9\r" expect -exact "#" set src $expect_out(buffer) regexp {(\d+.\d+.\d+.\d+)} $src match ipsrc puts "ADDRESS: $ipsrc" ./ssh 192.168.18.200 spawn ssh -o StrictHostKeyChecking=no test@192.168.18.200 Password: test-gw#sh ip int br | i Vlan9 Vlan9 192.168.18.200 YES NVRAM up up test-gw#ADDRESS: 192.168.18.200
03-16-2021 08:25 PM
the question arose, if we can do such checks in one script, ping / tracert, port status, how to separate them with brackets, and how to use timeout more correctly?
expect -exact "#" send -- "sh int des | i main | Main\r" expect -exact "#" set description $expect_out(buffer) regexp {(Gi0\/1\/0)|(Fa0\/0\/0)|(Fa0)|(Gi0)} $description match interface expect -exact "#" send -- "sh int $interface\r" #expect -exact "#" #send -- "sh ip int br | i Vlan9 \r" #expect -exact "#" #set src $expect_out(buffer) #regexp {(\d+.\d+.\d+.\d+)} $src match ipsrc #expect -exact "#" #send -- "ping $ipsrc\r"
03-18-2021 12:51 AM
Noticed an oddity, I checked in tclsh:
test-gw#tclsh test-gw(tcl)#set result [exec sh ip cef | i 0.0.0.0.*Vlan9] 0.0.0.0/0 192.168.100.2 Vlan9 test-gw(tcl)#regexp {([1-9]+.[0-9]+.[0-9]+.[0-9]+)} $result match int_back 1 test-gw(tcl)#puts $int_back 192.168.100.2
try in expect
expect "#" send -- "sh ip cef | i 0.0.0.0.*Vlan9 \r" expect "#" set dst $expect_out(buffer) regexp {([1-9]+.[0-9]+.[0-9]+.[0-9]+)} $dst ipshow puts "router is dst ip $ipshow"
but, it does not work, it gives an error
expect -d ssh 192.168.18.200 expect version 5.45.4 argv[0] = expect argv[1] = -d argv[2] = ssh argv[3] = 192.168.18.200 set argc 1 set argv0 "ssh" set argv "192.168.18.200" executing commands from command file ssh /*** DATE is Thu Mar 18 10:40:20 MSK 2021 ***/ spawn ssh -o StrictHostKeyChecking=no test@192.168.18.200 parent: waiting for sync byte parent: telling child to go ahead parent: now unsynchronized from child spawn: returns {29533} expect: does "" (spawn_id exp6) match glob pattern "*assword:"? no Password: expect: does "\rPassword: " (spawn_id exp6) match glob pattern "*assword:"? yes expect: set expect_out(0,string) "\rPassword:" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "\rPassword:" send: sending "123456\r" to { exp6 } expect: does " " (spawn_id exp6) match glob pattern "#"? no expect: does " \r\n" (spawn_id exp6) match glob pattern "#"? no test-gw# expect: does " \r\n\r\ntest-gw#" (spawn_id exp6) match glob pattern "#"? yes expect: set expect_out(0,string) "#" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) " \r\n\r\ntest-gw#" send: sending "sh ip cef | i 0.0.0.0.*Vlan9 \r" to { exp6 } expect: does "" (spawn_id exp6) match glob pattern "#"? no s expect: does "s" (spawn_id exp6) match glob pattern "#"? no h expect: does "sh" (spawn_id exp6) match glob pattern "#"? no expect: does "sh " (spawn_id exp6) match glob pattern "#"? no i expect: does "sh i" (spawn_id exp6) match glob pattern "#"? no p expect: does "sh ip" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip " (spawn_id exp6) match glob pattern "#"? no c expect: does "sh ip c" (spawn_id exp6) match glob pattern "#"? no e expect: does "sh ip ce" (spawn_id exp6) match glob pattern "#"? no f expect: does "sh ip cef" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef " (spawn_id exp6) match glob pattern "#"? no | expect: does "sh ip cef |" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef | " (spawn_id exp6) match glob pattern "#"? no i expect: does "sh ip cef | i" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef | i " (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0." (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0.0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0.0." (spawn_id exp6) match glob pattern "#"? no 0. expect: does "sh ip cef | i 0.0.0." (spawn_id exp6) match glob pattern "#"? no 0. expect: does "sh ip cef | i 0.0.0.0." (spawn_id exp6) match glob pattern "#"? no * expect: does "sh ip cef | i 0.0.0.0.*" (spawn_id exp6) match glob pattern "#"? no V expect: does "sh ip cef | i 0.0.0.0.*V" (spawn_id exp6) match glob pattern "#"? no l expect: does "sh ip cef | i 0.0.0.0.*Vl" (spawn_id exp6) match glob pattern "#"? no a expect: does "sh ip cef | i 0.0.0.0.*Vla" (spawn_id exp6) match glob pattern "#"? no n expect: does "sh ip cef | i 0.0.0.0.*Vlan" (spawn_id exp6) match glob pattern "#"? no 9 expect: does "sh ip cef | i 0.0.0.0.*Vlan9 \r\n" (spawn_id exp6) match glob pattern "#"? no test-gw# expect: does "sh ip cef | i 0.0.0.0.*Vlan9 \r\ntest-gw#" (spawn_id exp6) match glob pattern "#"? yes expect: set expect_out(0,string) "#" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "sh ip cef | i 0.0.0.0.*Vlan9 \r\ntest-gw#" can't read "ipshow": no such variable while executing "puts "router is dst ip $ipshow"" (file "ssh" line 60)
but if I change the regex like this:
expect "#" send -- "sh ip cef | i 0.0.0.0.*Vlan9 \r" expect "#" set dst $expect_out(buffer) regexp {([0-9]+.[0-9]+.[0-9]+.[0-9]+)} $dst ipshow puts "router is dst ip $ipshow"
then everything works, but only 0.0.0.0 gets into the selection
expect -d ssh 192.168.18.200 expect version 5.45.4 argv[0] = expect argv[1] = -d argv[2] = ssh argv[3] = 192.168.18.200 set argc 1 set argv0 "ssh" set argv "192.168.18.200" executing commands from command file ssh /*** DATE is Thu Mar 18 10:49:58 MSK 2021 ***/ spawn ssh -o StrictHostKeyChecking=no test@192.168.18.200 parent: waiting for sync byte parent: telling child to go ahead parent: now unsynchronized from child spawn: returns {1970} expect: does "" (spawn_id exp6) match glob pattern "*assword:"? no Password: expect: does "\rPassword: " (spawn_id exp6) match glob pattern "*assword:"? yes expect: set expect_out(0,string) "\rPassword:" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "\rPassword:" send: sending "123456\r" to { exp6 } expect: does " " (spawn_id exp6) match glob pattern "#"? no expect: does " \r\n" (spawn_id exp6) match glob pattern "#"? no test-gw# expect: does " \r\ntest-gw#" (spawn_id exp6) match glob pattern "#"? yes expect: set expect_out(0,string) "#" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) " \r\ntest-gw#" send: sending "sh ip cef | i 0.0.0.0.*Vlan9 \r" to { exp6 } expect: does "" (spawn_id exp6) match glob pattern "#"? no s expect: does "s" (spawn_id exp6) match glob pattern "#"? no h expect: does "sh" (spawn_id exp6) match glob pattern "#"? no i expect: does "sh i" (spawn_id exp6) match glob pattern "#"? no p expect: does "sh ip" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip " (spawn_id exp6) match glob pattern "#"? no c expect: does "sh ip c" (spawn_id exp6) match glob pattern "#"? no e expect: does "sh ip ce" (spawn_id exp6) match glob pattern "#"? no f expect: does "sh ip cef " (spawn_id exp6) match glob pattern "#"? no | expect: does "sh ip cef |" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef | " (spawn_id exp6) match glob pattern "#"? no i expect: does "sh ip cef | i" (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef | i " (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0." (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0.0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0.0." (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0.0.0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0.0.0." (spawn_id exp6) match glob pattern "#"? no 0 expect: does "sh ip cef | i 0.0.0.0" (spawn_id exp6) match glob pattern "#"? no . expect: does "sh ip cef | i 0.0.0.0." (spawn_id exp6) match glob pattern "#"? no * expect: does "sh ip cef | i 0.0.0.0.*" (spawn_id exp6) match glob pattern "#"? no V expect: does "sh ip cef | i 0.0.0.0.*V" (spawn_id exp6) match glob pattern "#"? no l expect: does "sh ip cef | i 0.0.0.0.*Vl" (spawn_id exp6) match glob pattern "#"? no a expect: does "sh ip cef | i 0.0.0.0.*Vla" (spawn_id exp6) match glob pattern "#"? no n expect: does "sh ip cef | i 0.0.0.0.*Vlan" (spawn_id exp6) match glob pattern "#"? no 9 expect: does "sh ip cef | i 0.0.0.0.*Vlan9 " (spawn_id exp6) match glob pattern "#"? no expect: does "sh ip cef | i 0.0.0.0.*Vlan9 \r\n" (spawn_id exp6) match glob pattern "#"? no test-gw# expect: does "sh ip cef | i 0.0.0.0.*Vlan9 \r\ntest-gw#" (spawn_id exp6) match glob pattern "#"? yes expect: set expect_out(0,string) "#" expect: set expect_out(spawn_id) "exp6" expect: set expect_out(buffer) "sh ip cef | i 0.0.0.0.*Vlan9 \r\ntest-gw#" router is dst ip 0.0.0.0
03-19-2021 04:05 AM - edited 03-19-2021 04:07 AM
it is not clear why, but changing the command
"sh ip cef | i 0.0.0.0. * Vlan9 \ r"
to
"sh ip cef | i 0.0.0.0/0 \ r" and it all worked
expect "#"
send -- "sh ip cef | i 0.0.0.0/0 \r"
expect "#"
set dst $expect_out(buffer)
regexp {([1-9]+.[0-9]+.[0-9]+.[0-9]+)} $dst ipshow
puts "router is dst ip $ipshow"
03-19-2021 04:08 AM - edited 03-19-2021 04:09 AM
Why with this code, the login to the device is successful only on the second attempt?
spawn ssh -o StrictHostKeyChecking=no $user@$host sleep 3 expect -exact "Password: " send "$pass\n"
*Mar 19 10:39:22.580: %SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: test] [Source: 172.18.7.22] [localport: 22] [Reason: Login Authentication Failed] at 10:39:22 UTC Fri Mar 19 2021 *Mar 19 10:39:22.584: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: test] [Source: 172.18.7.22] [localport: 22] at 10:39:22 UTC Fri Mar 19 2021
/*** DATE is Fri Mar 19 13:38:52 MSK 2021 ***/
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {590}
expect: does "" (spawn_id exp6) match exact string "Password: "? no
expect: does "\rPassword: " (spawn_id exp6) match exact string "Password: "? yes
expect: set expect_out(0,string) "Password: "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\rPassword: "
send: sending "123456\n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "#"? no
expect: does "\r\n" (spawn_id exp6) match glob pattern "#"? no
expect: does "\r\n\r\ntest-gw#" (spawn_id exp6) match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\r\n\r\ntest-gw#"
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide