我使用以下语法将公钥复制到主机,以便之后能够登录到主机而无需密码查询:
ssh-copy-id $hostname
其中$hostname
是带有用户名的系统主机名,例如root@123.456.789.100
. 但是,此命令需要至少一个密码查询,有时还需要一个额外的交互类型:
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)?
我试图用 解决我的问题expect
,这就是我目前所拥有的(包含所有评论和建议):
#!/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"
}
}
只要它正确地“捕捉”了第一个交互,而不是第二个交互,这就是有效的。似乎正在使用正确的密码(fg4,57e4h),但是当我尝试登录主机时,仍然要求我输入密码。我还检查了没有进入.ssh/authorized_hosts
。使用的密码也绝对正确,因为我可以将其复制并粘贴到登录。该脚本不会产生任何错误,但会产生以下exp_internal 1
输出:
./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 }
虽然我既不是 tcl 也不是期望专家,但似乎期望将正确的字符串(即密码)发送到ssh-copy-id
命令。但是,仍然存在问题,因为上述期望命令没有将公钥复制到主机。