Use expect in bash script to provide password to S

2018-12-31 17:10发布

问题:

To those who want to reply that I should use SSH keys please abstain

I\'m trying to use expect in an bash script to provide the SSH password. Providing the password works but I don\'t end up in the SSH session as I should, it goes back strait to bash.

My script:

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com\'
expect \"password\"
send \"$PWD\\n\" 
EOD
echo \"you\'re out\"

The output of my script:

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com\'s password: you\'re out

I would like to have my SSH session and only when I exit it to go back to my bash script. The reason why I am using bash before expect is because I have use a menu I can choose which unit to connect to.

Thanks

回答1:

Mixing bash and expect is not a good way to achieve the desired effect. I\'d try to use only Expect:

#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
#use correct prompt
set prompt \":|#|\\\\\\$\"
interact -o -nobuffer -re $prompt return
send \"my_password\\r\"
interact -o -nobuffer -re $prompt return
send \"my_command1\\r\"
interact -o -nobuffer -re $prompt return
send \"my_command2\\r\"
interact

Sample solution for bash could be:

#!/bin/bash
/usr/bin/expect -c \'expect \"\\n\" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }\'

This will wait for enter and than return (for a moment) interactive session.



回答2:

The easiest way is to use sshpass. This is available in Ubuntu/Debian repos and you don\'t have to deal with integrating expect with bash.

An example:

sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh user@192.168.1.200 ls -l /tmp

The above command can be easily integrated with a bash script.

Note: Please read Security Considerations section in man sshpass for full understanding of security implications.



回答3:

Add the \'interact\' expect command just before your EOD:

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com\'
expect \"password\"
send \"$PWD\\n\" 
interact
EOD
echo \"you\'re out\"

This should let you interact with the remote machine until you logout. Then you\'ll be back in bash.



回答4:

After looking for an answer for the question for months, I finally find a really best solution: writing a simple script.

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect \"assword:\"
send \"$password\\r\";
interact

Put it to /usr/bin/exp, then you can use:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Done!



回答5:

Use the helper tool fd0ssh (from hxtools, not pmt), it works without having to expect a particular prompt from the ssh program.



回答6:

Also make sure to use

send -- \"$PWD\\r\" 

instead, as passwords starting with a dash (-) will fail otherwise.

The above wont interpret a string starting with a dash as an option to the send command.



回答7:

A simple expect script

Remotelogin.exp

    #!/usr/bin/expect
    set user [lindex $argv 1]
    set ip [lindex $argv 0]
    set password [lindex $argv 2]
    spawn ssh $user@$ip
    expect \"password\"
    send \"$password\\r\"
    interact

Example:

    ./Remotelogin.exp <ip> <user name> <password>


回答8:

Another way that I found useful to use a small expect script from a bash script is as follows.

...
bash-script start
bash-commands
...
expect - <<EOF 
spawn your-command-here
expect \"some-pattern\"
send \"some-command\"
...
...
EOF
...
more bash commands
...

This works because ...If the string \"-\" is supplied as a filename, standard input is read instead...