1
sh ip cef | i 0.0.0.0.*Vlan9
0.0.0.0/0            192.168.18.200          Vlan9

I want to take only the ip address from it, that is, exclude 0.0.0.0/0 and Vlan9

I try it through expect, but for some reason it doesn't work

(?!Vlan9|0)\d+.\d+.\d+.\d+

expect -exact "#"
send -- "sh ip cef | i 0.0.0.0.*Vlan9 \r"
expect -exact "#"
set dst $expect_out(buffer)
regexp {(?!Vlan9|0)\d+.\d+.\d+.\d+} $dst match ipdst
#expect -exact "#"
#send -- "clear ip arp $ipdst\r"
#expect -exact "#"
puts "router is dst ip $ipdst"

by the way, expect -exact "#" - judging by the debug, it outputs each character on a separate line and does the gluing?

LOG

./ssh 192.168.18.200

/***  DATE is Wed Mar 17 12:42:57 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 {28141}

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 }
send: sending "sh ip cef | i 0.0.0.0.*Vlan9 \r" to { exp6 }

expect: does " " (spawn_id exp6) match glob pattern "#"? no


expect: does " \r\n" (spawn_id exp6) match glob pattern "#"? no
fractal
  • 13
  • 4

1 Answers1

0

Please try:

regexp {(?!Vlan9|0)(\d+\.\d+\.\d+\.\d+)} $dst match ipdst

or:

regexp {(?!Vlan9|0)\d+\.\d+\.\d+\.\d+} $dst ipdst
  • You need to surround the regex with parentheses to capture the submatch. In the second statement above, ipdst is assigned to the whole matched substring, which also makes a sense.
  • You need to escape the literal dot, otherwise it will match any character.

[EDIT]
If your expect version does not support lookaround assertions, please try instead:

regexp {(\d+\.\d+\.\d+\.\d+)\s+Vlan9} $dst match ipdst

or as a last resort:

regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)[^0-9]+Vlan9} $dst match ipdst

which will work with very old expect or tcl.

[EDIT]
Here is an example of ssh login transaction:

#!/usr/bin/expect

set host "localhost"            ;# change to your server name
set user "guest"                ;# user name
set pass "secret123"            ;# password

spawn ssh $host -l $user
expect "assword:"
send "$pass\n"
expect "Last login:"
expect "\$ "                    ;# command prompt (may differ depending on the system)
send "hostname\n"               ;# just an example; replace with your preferred command
expect "\n"                     ;# newline of the echo back of the sent command
expect "*\n"                    ;# wait for the server's response
set response $expect_out(0,string)
puts "server's response is $response"
tshiono
  • 21,248
  • 2
  • 14
  • 22
  • didn't help, i even tried like this [1-9]+.[0-9]+.[0-9]+.[0-9], but it also does not work, and if you do this - {(\ d +. \ d +. \ d +. \ d +)} then regexp writes the beginning of my expression - 0.0.0.0 and gives it – fractal Mar 17 '21 at 16:52
  • Thank you for the feedback. Your regex engine in `expect` may not support the `negative lookbehind assertion` `(?!Vlan9|0)`. I've added an alternative in my answer. Would you try it? – tshiono Mar 17 '21 at 23:30
  • thanks, I tried it, it also didn't work, the most interesting is why it works like this "([0-9] +. [0-9] +. [0-9] +. [0-9] +)" it's from the lines at the very beginning of the question, where I showed the output, takes the value "0.0.0.0", I change the expression to this "([1-9] +. [0-9] +. [0-9] +. [0- 9] +) "and it stops working ..... and I even checked it on the router, via tcl, everything works on it – fractal Mar 18 '21 at 07:38
  • Thank you for the trial and error. I feel sorry for not offering the working answer but I can not figure out why. I have added a `last resort` version which works with 20-year old expect or tcl. BTW your regex in your comment just above contains a whitespace between `[0-9]` and the following `+` sign. Is it a typo? – tshiono Mar 18 '21 at 08:01
  • so I can't understand why it works in one form, but you just change everything, the expression does not work ... yes, the space above is a typo, I wrote the same thing in EEM, I also checked that it all works in tcl on the device, but expect does not lend itself))) – fractal Mar 18 '21 at 12:45
  • @tshino apparently some kind of problem in the syntax - in cisco (. *) this is And, I changed it to "sh ip cef | i 0.0.0.0. * Vlan9" "sh ip cef | i 0.0.0.0/0" and it worked .. strange, in tcl everything was fine – fractal Mar 18 '21 at 13:41
  • tell me what they use expect -exact "#" for? with this line in the debug, you can see that the commands are entered line by line and glued together, and how to execute several commands correctly (do you need to separate them into blocks with brackets?), that is, as I did above with one, and I need to do several of these – fractal Mar 18 '21 at 13:49
  • First of all, why are you specifying the `-exact "#"` option? It tells `expect` to wait for the response `#` from the server. From where did you get the script you use? (It is your responsibility.) What about changing `expect -exact "#"` to `expect "*Vlan9"`? – tshiono Mar 19 '21 at 08:31
  • i found it here - [https://stackoverflow.com/questions/4566830/how-do-i-use-expect-to-connect-via-ssh-to-a-system-and-change-the-password-of th], expect command "#" (`expect' "#"`) - says that we are waiting for the given symbol to appear and after that we perform the action, right? what will it give me? (What about changing expect -exact "#" to expect "*Vlan9"?) usually have the lines `test-gw #` in the cli of the router after the hash, I can enter commands – fractal Mar 19 '21 at 08:50
  • The log message `expect: does " " (spawn_id exp6) match glob pattern "#"? no` tells you the server does not responding `#`. You will need to tweak the strings in `send` and `expect` in your script based on the actual interaction. – tshiono Mar 19 '21 at 09:07
  • `expect: does "" (spawn_id exp6) match glob pattern "Password: "? no` only this line, even at the very beginning, when it asks for a password, swears but enters it, it's strange – fractal Mar 19 '21 at 10:00
  • it turns out he sees the line "Password:" only on the second attempt, there may be some kind of expectation that needs to be entered? `expect: does "" (spawn_id exp6) match glob pattern "Password: "? no expect: does "\rPassword: " (spawn_id exp6) match glob pattern "Password: "? yes ` – fractal Mar 19 '21 at 10:12
  • for some reason, the login comes out only on the second attempt `* Mar 19 10: 27: 04.976:% SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: test] [Source: 172.18.7.22] [localport: 22] [Reason: Login Authentication Failed] at 10:27:04 UTC Fri Mar 19 2021 * Mar 19 10: 27: 11.520:% SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: test] [Source: 172.18.7.22] [localport: 22] at 10:27:11 UTC Fri Mar 19 2021 ` – fractal Mar 19 '21 at 10:31
  • As I cannot interact with your server, I cannot reproduce your transaction anyway. It's your own task. What you need is just convert the manual transaction with the server into the `expect` script. Very simple. BTW the `\r` at the beginning is not necessary. – tshiono Mar 19 '21 at 11:45
  • yes, I understand, you helped a lot, thank you. Could you show how you would make an ssh login script? through variables – fractal Mar 19 '21 at 12:37
  • I've posted an example of `ssh` login transaction just as a reference. You will need to modify some strings according to your system. Hope it helps. – tshiono Mar 19 '21 at 13:33
  • Yes, thanks, in principle everything is the same for me `spawn ssh -o StrictHostKeyChecking=no $user@$host sleep 3 expect "Password: " send "$pass\n" ` – fractal Mar 19 '21 at 13:55
  • Then please focus on the interaction of remote command execution. – tshiono Mar 19 '21 at 14:10
  • If you consider `everything is the same`, there is no reason your script does not work. Please find the difference carefully. – tshiono Mar 19 '21 at 14:21
  • at the moment, all commands are working successfully, regexp is also working out, your help was very helpful, now I plan to figure out how to hide the output of some commands from writing to the log, and also figure out how to properly store only the last 7 files in the log – fractal Mar 19 '21 at 14:29
  • Thank you for the feedback. Good to know it's working so far. If you consider your initial problem is solved with my answer, I'd appreciate if you can accept it by clicking on the check mark beside the answer. BR. – tshiono Mar 20 '21 at 02:10