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
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
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
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:
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>