0

I am seeking to automate ssh password based logins (and a series of actions after logging in).

I am aware that the ssh password prompt bypasses STDIN. To that end I put together a quick expect script.

spawn ssh -o StrictHostKeyChecking=No $USERNAME@$HOST

expect {
  timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
  eof { send_user "\nSSH failure for $HOST\n"; exit 1 }
  "*assword"
}

send "Pasword123\r"

expect {
  timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
  "*\$ "
}
sleep 1
send "echo 002-READY\r"
interact

This appeared to work as I expected. But when I feed further commands into STDIN of the running script after 'interact' they don't seem to arrive in the ssh session, e.g.

$ cat feed.sh
#!/bin/bash

sleep 3; echo "cat /etc/hosts" 

$ ./feed.sh | ./ssh_expect_script

However it does detect the EOF and terminates the session.

(Please don't tell me the solution is to use key-pairs; there are reasons why interactive passwords are a specific constraint.)

How do I get input routed via Expect to the remote session?

Alternatively, how can I send the password to ssh?

(Regarding the alternate question, I'm using PHP as the controlling mechanism. As a last resort, I could dynamicaly generate the whole expect script. I tried writing to the tty directly, but that just comes back on my screen. I also looked at ssh-askpass, but the documentation only mentions passphrases / I can't find a version that doesn't rely on have a desktop environment running).

2 Answers 2

0

Tcl and expect don't do anything automatic with stdin. You need to actively read it:

send "echo 002-READY\r"
expect -re {\$ $}

fconfigure stdin -blocking no
while {[gets stdin line] != 0} {
    # prevent an infinite loop waiting for data on stdin
    if {$line eq ""} break

    send "$line\r"
    expect -re {\$ $}
}

# finished sending the input: now log off gracefully
send "exit\r"
expect eof

A note about sleep -- typically you don't need to sleep after you send something if you have your expect patterns correct. I recommend you use expect -d program.exp while you're developing the script to verify that your patterns are matching.

3
  • 1) My script above finishes with interact which hands off the STDIO to the parent process 2) you do need to sleep to work around programs that flush stdin on startup.
    – symcbean
    Commented Jan 15, 2021 at 17:49
  • 2) I don't think so. Can you give an example? Commented Jan 15, 2021 at 17:51
  • Sorry - more correct to say that it connects the streams of its child process to its own STDIO therefore exposing them to the parent process.
    – symcbean
    Commented Jan 15, 2021 at 17:54
-1

Ah - needs a CR not a NL

echo -e "cat /etc/hosts\r"

(but if any can answer my second question...)

1
  • 3
    Considering that you obviously wrote this for the sake of others experiencing a similar problem, woudld you mind adding some explanation what this solves and how it does so?
    – AdminBee
    Commented Jan 15, 2021 at 15:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .