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"]