after the scp completes in this code an additional prompt appears. I've tried several things to prevent this from happening, but it still appears. To be clear, two prompts appear after the for loop and then the program continues.
#!/usr/bin/expect
# Set timeout
set timeout 1
# Set the user and pass
set user "user"
set pass "pass"
# Get the lists of hosts, one per line
set f [open "hosts.txt"]
set hosts [split [read $f] "\n"]
close $f
# Get the commands to run, one per line
set f [open "commands.txt"]
set commands [split [read $f] "\n"]
close $f
# Clear console
set clear "clear"
# Iterate over the hosts
foreach host $hosts {
# Establish ssh conn
spawn ssh $user@$host
expect "password:"
send "$pass\r"
# Iterate over the commands
foreach cmd $commands {
expect "$ "
send "$cmd\r"
expect "password:"
send "$pass\r"
}
# Tidy up
# expect "$ "
# send "exit\r"
# expect eof
# send "close"
}
Because both your hosts
and commands
lists end with an empty string. Verify with puts [list $hosts $commands]
So you send an empty command, which is just "hitting enter". Then you wait for the password prompt, time-out in 1 second, and carry on with the program.
This is due to the way you're reading the files: read
grabs the file contents, including the file's trailing newline. Then, when you split the string on newline, the list will include the empty string following the trailing newline.
Do this instead:
set commands [split [read -nonewline $f] "\n"]
# ........................^^^^^^^^^^
See https://tcl.tk/man/tcl8.6/TclCmd/read.htm
You could also do this
set f [open "commands.txt"]
while {[gets $f line] != -1} {
# skip empty lines and commented lines (optional)
if {[regexp {^\s*(#|$)} $line]} continue
lappend commands [string trim $line]
}
close $f