I have a script that connects to servers via ssh using expect and issues some commands.
When I run the expect script as HEREDOC it quits with an eof by the spawned shell after entering the Password, on the other hand when I run exactly the same script as a file it gives me a shell, how can this be?
I try to use this snippet:
expect -d /dev/stdin <<- END
sleep 10
set timeout 20
eval spawn "ssh user@example.org"
expect "user@example.org's password: " { send -- "Passw0rd\r" }
interact
END
But everytime I try to connect I get an 'received eof' and and expect exits, no shell.
expect: does "\ruser@example.org's password: " (spawn_id exp6) match glob pattern "rmh@user@example.org's password: "? yes
expect: set expect_out(0,string) "rmh@user@example.org's password: "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\rrmh@user@example.org's password: "
send: sending "Passw0rd\r" to { exp6 }
interact: received eof from spawn_id exp0
On the other hand when I open exactly the same script as a file I get connected.
cat <<- END > interact.expect
sleep 10
set timeout 20
eval spawn "ssh ssh user@example.org"
expect "user@example.org's password: " { send -- "Passw0rd\r" }
interact
END
expect -d interact.expect
I tried multiple times and double checked the scripts being identical.
Could someone explain how this could be?
The difference is what happens when you get to the interact
statement. This tells expect
to connect its stdin to the pty that's feeding to the current command.
When expect
is reading from a file, its stdin
is still connected to the terminal, so interact
will allow you to interact with the command using the terminal.
But when you use the here-doc, stdin
is connected to the here-doc, the terminal connection is lost to the expect
process. So expect
gets EOF because you've reached the end of the here-doc.
You would see the same thing if you used redirection to read from the file instead of using a filename argument:
expect -d /dev/stdin < interact.expect