I'd like have an unlimited (or very large) timeout for expect_user and the default timeout for expect. Is there a way to set different timeouts? Or would I just have to manually do it before every change in usage?
Both expect and expect_user support the -timeout option. Usually I would set the default timeout value in the timeout var and use the -timeout option for expect_user. For example:
set timeout 30; # the default timeout value
# don't time out when waiting for user's input
expect_user -timeout 100000 -re "(.*)\n"; # use -1 for infinite timeout
set user_input "$expect_out(1,string)"
Related
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
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>
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}.
Let me preface this question by saying I am VERY new to using tools like Expect, so the solution to this may be rather simple and obvious.
We are trying to automate the shutdown of our WebSphere server on our AS400 for a specific process that we have to run monthly. This happens by calling a CL program that runs a QSH session from a statement file. Actually calling the expect program seems to work fine.
The issue we run into is that it seems whatever sort of internal variable (presumably exp0) the expect is using to compare the expected text to isn't actually being attributed a new value when new commands get ran. Here is code in the statement file that gets ran:
#!/usr/local/bin/expect -f
set timeout 320
exp_internal 1
send "cd /qibm/proddata/websphere/appserver/v85/express/bin\r"
expect "$"
send "stopServer WAS85SVR\r"
expect {
default {exit 2}
"Username:" {send "username\r"; exp_continue}
"Password:" {send "password\r"; exp_continue}
"$"
}
expect "$"
The sends in the expect that say "username" and "password" would normally contain actual username and password text. Here is what gets dumped into the log file for the run:
send: sending "cd /qibm/proddata/websphere/appserver/v85/express/bin\r" to { exp0 cd /qibm/proddata/websphere/appserver/v85/express/bin
}
expect: does "" (spawn_id exp0) match glob pattern "$"? yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) ""
send: sending "stopServer WAS85SVR\r" to { exp0 stopServer WAS85SVR
}
expect: does "" (spawn_id exp0) match glob pattern "Username:"? no
"Password:"? no
"$"? yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) ""
expect: does "" (spawn_id exp0) match glob pattern "$"? yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) ""
The "\r"s have been included just for log file readability and I don't believe they end up translating into the sends that are passed. Also, it may be worth noting that the "stopServer" command runs for about 10 seconds before the "Username:" prompt shows up. We've tried putting in a delay prior to expecting for "Username:", but that didn't seem to work either.
If it is worth seeing, here is what a manual/interactive session in QSH looks like up to the "Username:" prompt:
$
> cd /qibm/proddata/websphere/appserver/v85/express/bin
$
> stopServer WAS85SVR
ADMU0116I: Tool information is being logged in file /QIBM/UserData/WebSphere/AppServer/V85/Express/profiles/WAS85SVR/logs/WAS85SVR/stopServer.log
ADMU0128I: Starting tool with the WAS85SVR profile
ADMU3100I: Reading configuration for server: WAS85SVR
Realm/Cell Name: <default>
Username:
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