title: How to use 'expect' to copy a public key to a host?
body: <p>I am using the following syntax to copy a public key to a host, in order to be able to log in afterwards to the host without password query: </p>
  
  <pre><code>ssh-copy-id $hostname 
  </code></pre>
  
  <p>in which <code>$hostname</code> is the hostname of the system with the username, e.g. <code>root@123.456.789.100</code>. However, this command requires at least one password query and - sometimes - an additional interaction of the type: </p>
  
  <pre><code>The authenticity of host 'xxx (xxx)' can't be established.
  RSA key fingerprint is xxx.
  Are you sure you want to continue connecting (yes/no)?
  </code></pre>
  
  <p>I tried to solve my problem with <code>expect</code>, and here is what I have so far (with all the comments and suggestions incorporated): </p>
  
  <pre><code>#!/usr/bin/expect
  set timeout 9
  set hostname     [lindex $argv 0]
  
  spawn ssh-copy-id $hostname 
  
  expect {
    timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
    eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
  
    "*re you sure you want to continue connecting" {
      send "yes\r"
      exp_continue    
    }
    "*assword*" {
     send  "fg4,57e4h\r"
    }
  
  }
  </code></pre>
  
  <p>This works so far as it 'catches' the first interaction correctly, but not the second one. It seems, that the correct password (fg4,57e4h) is being used, but when I try to log in to the host machine, I am still asked for a password. I also checked that no entry in <code>.ssh/authorized_hosts</code> have been made. The used password also is absolutely correct, as I can just copy and paste it to log-in. The script does not create any error, but produces the following <code>exp_internal 1</code> output: </p>
  
  <pre><code> ./expect_keygen XXX
  spawn ssh-copy-id XXX
  parent: waiting for sync byte
  parent: telling child to go ahead
  parent: now unsynchronized from child
  spawn: returns {3602}
  
  expect: does "" (spawn_id exp6) match glob pattern "*re you sure you want to continue connecting"? no
  "*assword*"? no
  XXX's password: 
  expect: does "XXX's password: " (spawn_id exp6) match glob pattern "*re you sure you want to continue connecting"? no
  "*assword*"? yes
  expect: set expect_out(0,string) "XXX's password: "
  expect: set expect_out(spawn_id) "exp6"
  expect: set expect_out(buffer) "XXX's password: "
  send: sending "fg4,57e4h\r" to { exp6 }
  </code></pre>
  
  <p>Although I am neither tcl nor expect expert, it seems expect sends the correct string (i.e. the password) to the <code>ssh-copy-id</code> command. But still, there must be a problem as the above expect command <strong><em>does not</em></strong> copy the public key to the host.</p>