I have a script that must perform a 'sudo' operation on each of a number of hosts. I'm trying to get expect working so I only have to enter it once, and have run into a couple of issues.
First, several examples suggest to use:
/usr/bin/expect <<EOD
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
EOD
However, as soon as I enter the second '<', all of the quoting gets screwed up, and my script will terminate with an unexpected end of file. This is really strange, as I use the same mechanism with cat to write out files in other scripts.
Other examples suggest:
/usr/bin/expect -c "
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
"
Doing it this way (and adding -d to expect), I get errors about no tty and a repeat of my password with an 'n' appended to the end, so it isn't sending a newline (I've tried '\r' as well), but instead appears to be escaping the 'n'
Since most of the examples I'm finding are from Linux, I expect (ha, ha, pun not intended!) that they're using a GNU expect, and I'm using a BSD expect. I am reading through the man page, but the word "spawn" appears so many times, it could be quite a while before I stumble across the correct instance.
Here's a result that seems to be closest to working:
flamingo:~ jnojr$ Scripts/getinfo_expect.sh
Assuming you have one 'sudo' password for all of your hosts, enter it now:
expect version 5.45
spawn /usr/bin/ssh -t macbook /usr/bin/sudo -v
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {67358}
expect: does "" (spawn_id exp7) match glob pattern "Password:"? no
Password:
expect: does "Password:" (spawn_id exp7) match glob pattern "Password:"? yes
expect: set expect_out(0,string) "Password:"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "Password:"
send: sending "password\n" to { exp7 }
argv[0] = /usr/bin/expect argv[1] = -d argv[2] = -c argv[3] =
spawn /usr/bin/ssh -t macbook /usr/bin/sudo -v
expect Password: { send password\n }
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
sudo: no tty present and no askpass program specified[/CODE]
That's with leaving the '\n' outside of the quotes, as in
send "$SUDOPASS"\n
It seems to be mostly working, except skipping the '-t' option to ssh
I second @BrianCain's comment that passwordless ssh
w/sudo
would be a better solution. That said, let's try to help with your expect
script and you can decide whether it continues to be too much of a headache.
I believe you're going to want to use expect -f -
(read the script from STDIN) when using the bash
"here string" (<<
) to input the script to expect
. So:
/usr/bin/expect -f - <<EOD
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
EOD
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With