我正在尝试创建一个自动输入密码的脚本" root"将ssh-key从A复制到B.由于ssh-copy在B上不起作用,也无法安装我使用过:
ssh root@$ip mkdir -p .ssh
cat "~/.ssh/id_rsa.pub" | ssh "root@$ip" 'cat >> .ssh/authorized_keys'
转移密钥。但是B在重启时删除了它的存储空间。所以我必须自动化这个过程。我认为期望脚本是最简单的解决方案?然而,我对这些并不十分熟悉。
#!/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
它似乎一直有效,直到第一次发送。然而然后卡住并等待输入? (错误的期待?)
答案 0 :(得分:3)
这是您遇到问题的部分:
spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"
发送密码后,您需要等待30秒才能显示(yes/no?
,但如果您之前已连接到该计算机,则可能无法显示。您希望有条件地期望y / n提示:
spawn ssh "root@$ip mkdir -p .ssh"
expect {
"(yes/no)? " { send "yes\r"; exp_continue }
"password:" { send "root\r" }
}
expect eof
expect命令的这种形式允许您同时查找多个字符串。如果看到的第一个是"(是/否)? ",然后发送"是"继续这个期望命令。当您看到"密码:"时,发送密码并让expect命令结束。
您可能想要更改第二个spawn命令 所以shell可以处理管道。
set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd
答案 1 :(得分:0)
spawn
无法按照您希望的方式处理输入重定向。
最简单的解决方案是创建一个单独的shell脚本来执行复制,让expect
只处理密码提示。
这对我有用:
cat copykey.sh
:
#!/bin/bash
ssh user@host "cat >> .ssh/authorized_keys" < ~/.ssh/id_rsa.pub
cat copykey.expect
:
#!/usr/bin/expect -f
set timeout 30
spawn ssh user@host mkdir -p .ssh
expect "password:"
send "password\n"
expect "$ "
spawn ~/copykey.sh
expect "password:"
send "password\n"
expect "$ "
答案 2 :(得分:0)
需要提供ip,username,password作为命令行参数(Remotelogin.exp)
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect {
"(yes/no)?" {
send "yes\r"
expect "password:"
send "$password\r"
}
"password:" {
send "$password\r"
}
}
`
示例:./ Remotelogin.exp