expect telnet - command not executing - shell

I am struggling with executing command via telnet/expect.
set send_slow {500 .5}
send -s -- "show slot *\r"
expect {
".*>" {
send -s -- "y\r"
exp_continue
}
".*#\s"
}
send -s "who\r"
expect "# "
send -s "alm\r"
expect "# "
send -s -- "logout\r"
show slot command prints card in slots. Due to paging user is asked to continue. After execution that a prompt NODE2-1# is shown and I want to execute command who.
What I get is:
2/36 PF Empty Up Down UEQ
2/37 FAN FAN Up Up
2/38 Empty Empty Down Down UAS UEQ
2/39 Empty Empty Down Down UAS UEQ
25/1 SFD40 SFD40 Up Up
Node2-1#<br> Node2-1# who
Session Username Date Terminal
-------------------------------------------------------------------------------
116 (cli tel) * admin May 29 06:57 XX.X.XX.XX
Node2-1# almlogout
Alarm Status: Critical-3 Major-0 Minor-0
As you can see, first prompt is left empty and in second one there is a command. It takes few seconds to execute it.
Moreover, below one can see, that in prompt there is pasted command almlogout. These two are separate commands -> alm and logout. However, they are pasted together.
Question is - how to execute command in prompt without that delay, and second - how to separate two commands

By default, expect statement's pattern is in glob style so ".*>" should be -re ".*>" and ".*#\s" should be -re ".*#\\s" or -re {.*#\s} ("\s" is actually "s").
And since .* can match nothing, so -re {.*>} is the same as -re {>} and -re {.*#\s} the same as -re {#\s}.

Related

expect script capturing garbage characters - need to remove

I have a switch I'm trying to write to grab output from a hp switch. The source machine is an ubuntu 18.04. The code version on the switch is 16.04. I tried changing the terminal settings on the switch from the default of vty100 to ansi and none but no difference. How do I get rid of the extra special characters show below?
set timeout 20
spawn ssh -l manager 192.168.10.10
expect "manager#192.168.10.10's password:"
send "admin\n"
expect "Press any key to continue"
send "j\n"
log_file -a hp.log
send "show vlan 10\n"
expect "labswitch#"
send "conf\n"
send "hostname newswitch\n"
expect "newswitch#"
send "exit\n"
expect "newswitch#"
send "logout\n"
I have this extra output of characters through each part of the script in the log file and the console. Need to remove these characters from output. ??
^[[?6l^[[1;30r^[[?7h^[[2J^[[1;1H^[[1920;1920H^[[6n^[[1;1HYour previous successful login (as manager) was on 2019-03-07 $ from 192.168.10.4
^[[1;30r^[[30;1H^[[30;1H^[[2K^[[30;1H^[[?25h^[[30;1H^[[30;1labswitch# ^[[30;1H^[[30;11H^[[30;1H^[[?25h^[[30;11H^[[1;0H^$ Status and Counters - VLAN Information - VLAN 10
VLAN ID : 10
Name : Server_Lab
Status : Port-based
Voice : No
Jumbo : Yes
Private VLAN : none
Associated Primary VID : none
Associated Secondary VIDs : none
Port Information Mode Unknown VLAN Status
---------------- -------- ------------ ----------
11 Tagged Learn Up
12 Tagged Learn Up
^[[1;30r^[[30;1H^[[30;1H^[[2K^[[30;1H^[[?25h^[[30;1H^[[30;1H
Those are ANSI Escape sequences
You should be able to strip them out of the log file with:
send "logout\r" ;# idiomatically, use \r to "hit enter"
log_file ;# turn off logging
# read the log file
set fid [open hp.log r]
set contents [read -nonewline $fid]
close $fid
# remove the escape sequences
regsub -all {\033\[(?:\?|\d+;)?\d+[[:alpha:]]} $contents {} stripped
# write the new contents
set fid [open hp.log w]
puts $fid $stripped
close $fid

How can I prevent expect from ignoring new lines?

In my current, draft script, the show command output is fine, but once I hit the "conf" commands, the output is pressed together. How do I fix this?
set timeout 20
spawn ssh -l manager 192.168.41.10.10
expect "manager#192.168.10.10's password:"
send "admin\r"
expect "Press any key to continue"
send "j"
log_file hp.log
send "show vlan 10\r"
expect "newsw*"
send "conf\r"
expect "newsw*(config)"
send "\r"
send "vlan 45\r"
expect "newsw*"
send "tagged 3\r"
send "exit\r"
send "exit\r"
The is what the log looks like for the "conf" section and related commands. The output is running together. You can see a piece of the "show vlan 45" at the end.
newswitch# confnewswitch(config)# vlan 45newswitch(vlan-45)# tagged 3newswitch(vlan-45)# exitnewswitch(config)# exitnew$ Status and Counters - VLAN Information - VLAN 45
VLAN ID : 45
Name : VLAN45
Here is the proper / desired output. I would think that it would look like this:
newswitch#
conf
newswitch(config)# vlan 45
newswitch(vlan-45)# tagged 3
newswitch(vlan-45)# exit
newswitch(config)# exit
newswitch$ show vlan 45 ....and so forth

Expect script not sending command

I am using expect to deal with an embedded system's U-boot.
However, my script is not sending command at certain point.
Here is my script
#!/usr/bin/expect
set scriptaddr "0x32000000"
spawn screen /dev/ttyUSB1 115200
expect "Hit any key to stop autoboot:"
send "\r"
puts "Start flashing"
send "tftp $scriptaddr recovery_files/install.scr \r"
sleep 2
send "source 0x32000000\r"
## here start the flashing process which takes 15 mins
## this is the part where not working ##
expect "(Please reset your board)"
sleep 3
send "reset\r"
And this is the last part showing at the console which waiting user to key in "reset"
#################################################################
#################################################################
###
2 MiB/s
done
Bytes transferred = 7333121 (6fe501 hex)
Uncompressed size: 168820224 = 0xA0FFE00
MMC write: dev # 0, block # 3940352, count 329727 ... 329727 blocks written: OK
============ INSTALLATION IS DONE =============
(Please reset your board)
machine#
Any mistake i have made? Please assist, thank you!
By default expect will have a 10seconds timeout.
Solution : set timeout <time in second>

How can I send characters at specific delays to a telnet address?

Note: i have not included exact addresses for privacy reasons.
Here is the procedure I would like to be able to do:
I am first proceeding into telnet as follows.
telnet <myaddress> <myport>
Then, the following message appears, followed by a flashing cursor
Trying <some address>...
Connected to <cloud address>.
Escape character is '^]'.
At this stage, I would like to enter Two Carriage Returns (ASCII 13 or '\r') spaced 100 milliseconds apart.
--
How can I achieve this while in telnet mode that does not require me to manually hit Carriage Return at the right timing?
Pipe the output of a command or script that outputs the characters you want with appropriate timing.
{ printf '\r'; sleep .1; printf '\r'; } | telnet <myaddress> <myport>

How to grab 'show tech' with bash and expect?

I'm using 2 scripts. A bash and an expect script. the bash is just a for loop with a set of IPs. If I can, I would use the expect script to create a variable near the beginning, right after login. It would look for the hostname, assign it to a variable, then use that variable as the 'match' after show tech output.
Also, the IPs are example. I'm not actually expecting (no pun intended) this to operate on public DNS IPs. Ok ok, you got me, I put this disclaimer here just so I could 'not' make that pun.
#!/bin/bash
arrayHOST+=( '8.8.8.8' '8.8.4.4' '4.2.2.2' '4.2.2.1' )
username="user1"; password="pass1"
for host in ${arrayHOST[#]}; do
./expect.sh $host $username $password >> $host.txt
done
and the expect script:
#!/usr/bin/expect -f
#log_user 0
set timeout -1
set varIP1 [lindex $argv 0]
set varUSER [lindex $argv 1]
set varPASS [lindex $argv 2]
spawn telnet $varIP1
expect "Username:"
send "$varUSER\r"
expect "Password:"
send "$varPASS\n"
expect "#"
send "term leng 0\r"
expect "#"
send "term wid 0\r"
expect "#"
send "show tech\r"
expect "#"
puts $expect_out(buffer);
Problem is that there are '#' characters that match before the command finishes so I don't get to capture the whole thing. Points to consider:
The end of the output from 'show tech' isn't the same on every device in the IP list unless you consider the hostname of the device itself.
Yes, I know I can "show tech | redirect tftp:// etc". This wont help me achieve the desired results.
I've tried 'not expecting anything' but this causes expect to not capture anything. (sending show tech without following with a new line containing expect "#" or anything else)
spawn telnet 8.8.8.8
Trying 8.8.8.8...
Connected to 8.8.8.8.
Escape character is '^]'.
User Access Verification
Username: benjamin
Password:
rowtar#term leng 0
rowtar#term wid 0
rowtar#term wid 0
rowtar#
I really like the idea of trying to regex/match an expect variable to the output that matches the hostname of the device but I don't how to do that. In my example, I would try to match "rowtar#" but without per-defining that ahead of time or before the expect script is called.
The solution was looking me right in the face.
Simply:
expect -re #$
matching any line ending with #
I still encourage someone to help/answer with hostname matching to a variable

Resources