How to send commands stored in a file when using Expect - bash

I'm writing a script that will eventually execute a list of commands on a switch (via SSH). These commands are stored in a file and the number of commands will vary
However, I'm not sure how this can be done using Expect. I know Expect can use a while loop, but I can't find a clear example. can someone here help?
/usr/bin/expect <<EOD
spawn ssh -o StrictHostKeyChecking=no admin#$switch
expect "*Enter password for admin\:"
send "password\r"
expect "*#"
send "????"
there should be a while loop that reads line by line from a file called "commands" that looks like this
command 1
command 2
command 3
...

Extreme Networks XOS has an XML API. You can use this for executing arbitrary commands. See the ExtremeXOS XML API Developer Guide which is listed on the support documentation page.
Managing switches by expect-scripting their CLIs is often erratic and error prone, I'd recommend that you avoid doing so if possible.

Related

standard expect works but xargs does not

I am currently trying to improve my script when using snmpwalk and wanted to incorporate using xargs as this would help me gather information from multiple devices at the same time. Taking small steps I created a simple expect file with the following code:
#!/usr/bin/expect -f
set hostname [lindex $argv 0]
spawn snmpwalk $hostname
interact
From there I created a simple bash script to test the functionality of it with the code here:
#!/bin/bash
cfg=$(cat ./ips)
for c in $cfg
do
expect ./EXPECT/01.exp $c
done
Doing this produces the proper information but takes time as it goes through each IP, one at a time.
I then commented the above code out and created the xargs version here:
#!/bin/bash
xargs -I ADDRESS -P4 expect ./EXPECT/01.exp ADDRESS < ./ips
Once I run the bash script, nothing is produced other then the command from the expect file echoing with no other action. I then looked into it and saw that you can add a "-noecho" switch to it but this didn't fix anything.
I then changed the spawn command to exec but the same issue happens and nothing is shown other then an echo of the command.
Would be interested to see what issue could be causing this.
So the answer was rather simple and a bit embarrassing. The expect file needs some type of expect statement before it will run correctly. I simply put in the following expect syntax regardless if it would see this or not and it worked fine:
expect {
"(yes/no)?" {
send "yes\r"
exp_continue
}
}
From here the script worked as expected and it began to run 4 IP's at a time.

Passing variable to Expect and Spawn

I'm writing a script that will scp a tar file from my local server to a remote host. Since the script generates the file through a pre-requisite process, the name is generated dynamically. My script needs to take the name of the file and pass it to scp for transfer.
#!/usr/bin/expect -f
spawn scp test.$(date +%y%m%d_%H%M).tar user#IP-ADDRESS:/destination/folder
set pass "password"
expect "password: "
send -- "$pass\r"
expect eof
I've tried setting the filename as a variable but keep seeing the same error:
can't read "(date +%y%m%d_%H%M)": no such variable
while executing "spawn scp test.$(date +%y%m%d_%H%M).tar user#IP-ADDRESS:/destination/folder"
$(date +%y%m%d_%H%M) is not a Tcl command. If you use expect, you have to learn Tcl. To get a formatted date in Tcl, use the clock command. Also, interpolation of the result from a command in Tcl is not done by $(....), but by [....]. You can find examples for this construct here.
Decided to go another route since the team was able to provision a new Artifactory repo for this binary and alike. However, to the advice provided here I was able to make a few discoveries which I used to fix my issues:
I also had a password with $ symbol and that also caused a world of issues.
#!/bin/bash
TEST=$(date +%y%m%d_%H%M)
/usr/bin/expect <<eof
set password {pas\$word}
spawn scp "$TEST" user#IP-ADDRESS:/destination/folder
expect "*password:"
send "$pasword\r"
expect eof

Pass password for download script

I'm downloading huge files and have a python downloading script. Since the data are to huge to be stored in their original format, I only download a couple of years, process them, then delete the original before I download the next few years. For every set of years I have a separate download script and I just build a quick bash script to run them
#!/bin/bash
python download_1901-1909.py
## processing, delete
python download_1910-1919.py
## processing, delete
python download_1920-1929.py
## processing, delete
[...]
For the download scipt, I have to type in a password. I know it's is possible to do some automatic password passing with spawn, but I couldn't make it work. Trying the spawn thing does this
#!/usr/bin/expect -f
spawn python download_1901-1909.py
expect "Password:"
send "mypassword"
interact
yields
sh test.sh
test.sh: line 2: spawn: command not found
couldn't read file "Password:": no such file or directory
test.sh: line 4: send: command not found
test.sh: line 5: interact: command not found
How can I pass a password to a python download script?
This answer is trying to solve your question of finishing what you need, not the question of executing a #!/usr/bin/expect, which may be what you are asking.
You may try to use the -c param of expect inline.
For example,
#!/bin/bash
expect -c "spawn python download-1901_1909.py; expect \"assword\"; send \"mypassword\r\n\"; interact"
expect -c "spawn python download-1910_1919.py; expect \"assword\"; send \"mypassword\r\n\"; interact"
# and the remaining, similarly
Note:
Your send part may need to send the \r\n to "simulate" the Enter key of finishing enter the password.
You may use sed within a for to simply the lines.
"assword" is to prevent the case of first letter of that word, "Password" vs "password", for some portability.

automate getting diagnostic files from a controller via ssh commands

I'd like to automate getting diagnostic files from a controller that responds to ssh commands, like e.g.
ssh diag#controller tarred > diags.tgz
Unfortunately, I have to type a password to make the above command go through.
What have I considered to get around that:
using ssh keys: not possible, since I can't login to the controller, it just expects commands and doesn't offer a shell
using ssh-pass package: I don't have admin rights on the machine and can't install packages
using "expect": works to some extent, but the resulting file is corrupted.
Here's the "expect" script I've used:
#!/usr/bin/expect -f
log_user 0
set timeout 300
spawn ssh diag#controller tarred
expect "?assword:"
send "unrealpassword\r"
expect \r\n
log_user 1
expect eof
The script makes sure that only the required output gets stored with the "log_user" commands until eof is encountered.
I've piped this script to a file and that file is corrupted, i.e. it's either too short (because of a timeout?) or too long (?).
Any idea about what goes wrong here.?

Exporting data from expect script

so i've written a short expect script which logs into a APC Power Distribution Unit interface via telnet and polls the current ampage.
#!/usr/bin/expect
set ip "192.168.0.1"
set username "myusername"
set password "mypassword"
spawn "/bin/bash"
send "telnet $ip\r"
expect "*User Name*"
send "$username\r"
expect "*Password*"
send "$password\r"
expect "*APC*"
send -- "phReading all current\r"
expect "*Success*"
send "quit\r"
expect eof
The script does its job and I see the amps on screen, displayed like this:
apc>phReading all current
E000: Success
1: 7.5 A
apc>quit
What i need to do is 'export' that 7.5 figure, either to a text file or pass it to a bash script as a variable.
Any ideas on how i can do this?
Thank you!
Expect is an extension of TCL, so you have access to all of TCL's constructs.
If I were you I would have the expect script write directly to a file.
See the section "Writing a file" here: http://wiki.tcl.tk/367. It has a simple example for just that. In your case, you will want to open the file for append (a) instead of write (w).
open command documentation at: http://www.tcl.tk/man/tcl8.6/TclCmd/open.htm
Let me know how that works for you.

Resources