Skip to content
Advertisement

iterating ssh-copy-id command to copy on multiple hosts

I am trying to copy public key to my multiple hosts in a file called “hostsfile”. I am writing a script that will allow me to do that as I am setting a dev environment and I may end up doing it over and over. Googling around I have been able to place insert the public key using ssh-copy-id command and have been able to automate it for one host. However the code needs to be fine tuned to go through each and every host in the hostsfile…unfortunately it completes the first entry and then exits: Below is the code… Appreciate any help in advance….

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
set hosts [split [read $f] "n"]
close $f

set exp_internal 1
foreach host $hosts {
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect_after eof { exit 0 }
    expect "password:" { send "vagrantr" }
    expect_after eof { exit 0 }
    expect "$ "
    }
send "exitr"
expect eof

Glen this is what I made out of your comments…. Can you advise please and if you dont mind help with the complete code:

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
close $f

set hosts [split [read -nonewline $f] "n"]

foreach host $hosts {
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:" 
    send "vagrantr"
    expect eof
}
puts done

Hi Glen it worked with the following code as you suggested. However if the key already exists on one of the hosts the process terminates. can you suggest how i can add if/else state for it to not break if the remote host responds with key already exists? Thanks for your help in advance.

Below is the code that worked for the first problem.

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
set hosts [split [read -nonewline $f] "n"]
close $f


foreach host $hosts {
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:"
    send "vagrantr"
    expect eof
}

puts done

Advertisement

Answer

You have instructed expect to exit after eof. Don’t do that.

foreach host $hosts {
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:" 
    send "vagrantr"
    expect eof
}
puts done

Note that your $hosts list has an empty last element. Use read -nonewline to read the file:

set hosts [split [read -nonewline $f] "n"]
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement