I am trying to make a script which automatically enters the password "root" to copy the ssh-key from A to B. Since ssh-copy does not work on B and also cant be installed i used:
ssh root@$ip mkdir -p .ssh
cat "~/.ssh/id_rsa.pub" | ssh "root@$ip" 'cat >> .ssh/authorized_keys'
To transfer the key. But B delets its storage on reboot. So i have to automate this process. I thought a expect script would be the simplest solution? I am however not very experienced with these.
#!/usr/bin/expect
#31.09.2015
set timeout 30
spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"
spawn cat "~/.ssh/id_rsa.pub" | ssh "root@$ip" 'cat >> .ssh/authorized_keys'
expect "password:"
send "root\r"
interact
It seems to works till the first send. Then however gets stuck and waits for an input? (wrong expect?)
This is the part you're having trouble with:
spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"
After you send the password you're waiting 30 seconds for (yes/no?
to appear, but it might not appear if you've connected to that machine before. You want to conditionally expect that y/n prompt:
spawn ssh "root@$ip mkdir -p .ssh"
expect {
"(yes/no)? " { send "yes\r"; exp_continue }
"password:" { send "root\r" }
}
expect eof
That form of the expect command allows you to look for multiple strings simultaneously. If the first one seen is "(yes/no)? ", then send "yes" and continue with this expect command. When you see "password:", send the password and let the expect command end.
You might want to change the second spawn command so a shell can handle the pipeline.
set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd