1

I need to login through ssh twice with a script and can't get it to work. This is what I have in my script file:

#!/usr/bin/expect

set login "user"
set addr "address1"
set addr2 "address2"
set pw "password"

spawn ssh $login@$addr
expect "$login@$addr\'s password:"
send "$pw\r"
expect "$login@host:"
spawn ssh $addr2
expect "$login@$addr\'s password:"
send "$pw\r"
interact

but this fails with the error:

user@host:~$ ssh: Could not resolve hostname address2: Name or service not known
send: spawn id exp7 not open
    while executing
"send "$pw\r""

If I change the line spawn ssh $addr2 with exec ssh $addr2 it fails with the error:

user@host:~$ ssh: Could not resolve hostname address2: Name or service not known
    while executing
"exec ssh $addr2"

What do I need to change in order to make this work?

Gabriel
  • 1,060
  • 5
  • 15
  • 28
  • 2
    Rather than hard-coding passwords into an expect script, I'd try and use key pairs for doing the logins instead. – kurtm Oct 09 '13 at 23:41
  • Yeah but that would only make the script more complicated and I can't get it to work as it is. Leaving the password written explicitly doesn't bother me that much (at least for now) – Gabriel Oct 09 '13 at 23:45
  • 1
    If you set up the key pairs you wouldn't have to send the passwords, it would just work. So I'd argue it would be less complicated. But yes, that still leaves the script broken, which is why I made the comment and not an answer. – kurtm Oct 09 '13 at 23:47
  • 1
    I don't even know what "key pairs" are so I'd argue that to me it would be quite a bit more complicated :) – Gabriel Oct 09 '13 at 23:55

3 Answers3

4

Posting my own answer since I found a way around this issue. Here's the script that actually works:

#!/usr/bin/expect

set login "user"
set addr "address1"
set addr2 "address2"
set pw "password"

spawn ssh $login@$addr
expect "$login@$addr\'s password:"
send "$pw\r"
expect "$login@host:"
send "ssh $addr2\r"
expect "$login@$addr\'s password:"
send "$pw\r"
interact

So basically I replaced the line spawn ssh $addr2 with send "ssh $addr2\r". I was trying to spawn another ssh from where I started instead of starting another ssh on the host I first ssh'd to.

kurtm
  • 7,055
Gabriel
  • 1,060
  • 5
  • 15
  • 28
2

ssh is unable to resolve the hostname you are giving it, and so it errors out. You are then telling expect to send the password, but there is nothing to send it to since ssh threw the error and quit. So you need to check the hostname you are giving it, since it isn't resolving. Or you can switch to an IP address. But it is probably better to find out why it can't figure out who "address2" is.

kurtm
  • 7,055
  • But the hostname is correct. If I use the exact same command ("ssh address2") after the first login, I get no errors. – Gabriel Oct 09 '13 at 23:50
  • Clearly ssh doesn't agree though. So we need to figure out why it feels that way. You say it works after the first login, at what point are you getting the error message in the question? – kurtm Oct 09 '13 at 23:56
  • The first login works whether I do it manually or with the script. The second login only works if I type ssh address2 manually. If I use the script, it sends spawn ssh address2 which fails with the mentioned error. – Gabriel Oct 10 '13 at 00:01
  • What if you specify the username for the second spawn? – kurtm Oct 10 '13 at 00:07
  • How would I do that? – Gabriel Oct 10 '13 at 00:09
  • @Gabriel How about like you do for the first one? The first one you do spawn ssh $login@$addr. But you don't specify login for the second one. – kurtm Oct 10 '13 at 00:12
  • I get the same error :( – Gabriel Oct 10 '13 at 00:14
  • I've fixed it :) – Gabriel Oct 10 '13 at 00:19
  • 1
    @Gabriel Make sure to share the answer for future folks with your problem. – kurtm Oct 10 '13 at 00:21
  • Done. Not sure why spawn does not work but I'm glad it works now. Thank you for your help! – Gabriel Oct 10 '13 at 00:24
2

Lookup ssl key generation. You generate a pair of keys (public and private), you keep the private key(s) you generate on your system, and place the public keys on systems you need to access through ssh. Then ssh does not prompt you for password, and you don't need expect.

Here is a script, "sskkeygen.sh", I use to generate keys, so I can generate different keypairs for different systems,

#!/bin/bash
SYSTEM=${1:-boogie}
COMMENT=${2:-"Key for $SYSTEM work"}
ssh-keygen -t dsa -f ~/.ssh/id_dsa.$SYSTEM -C "$COMMENT"
chmod 600 ~/.ssh/id_dsa.$SYSTEM
chmod 600 ~/.ssh/id_dsa.$SYSTEM.pub

Copy the ~/.ssh/id_dsa.$SYSTEM.pub key to the remote system. Be Careful - the instructions all say copy the keyfile, but you want to append it!

Then you need a file ~/.ssh/config which tells which keys to use for which hosts.

#key: prod
Host 1.2.3.4
  IdentityFile ~/.ssh/id_dsa.prod
  User meself

#key: dev/test
Host 2.3.1.4
  IdentityFile ~/.ssh/id_dsa.dev
  User meself

#key: ftp dropbox
Host dropbox.company.com
  IdentityFile ~/.ssh/id_dsa.dropbox
  User virtualuser

#key: ftp thing
Host aaa.bbb.thing.com
  IdentityFile ~/.ssh/id_dsa.think
  User neato

#key: work
Host *.work.com
  IdentityFile ~/.ssh/id_dsa.work
  User workid