期待脚本 - 自动密码
Expect Script - Auto Password
我正在尝试制作一个自动输入密码 "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 在重新启动时删除了它的存储。所以我必须自动化这个过程。我认为 expect 脚本是最简单的解决方案?然而我对这些不是很有经验。
#!/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
它似乎在第一次发送之前有效。然后卡住并等待输入? (错误的期望?)
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 "$ "
这是您遇到问题的部分:
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 命令的这种形式允许您同时查找多个字符串。如果看到的第一个是“(yes/no)?”,则发送 "yes" 并继续此 expect 命令。当看到"password:",发送密码,让expect命令结束。
您可能想要更改第二个生成命令
所以 shell 可以处理管道。
set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd
需要提供ip、用户名、密码作为命令行参数(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
我正在尝试制作一个自动输入密码 "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 在重新启动时删除了它的存储。所以我必须自动化这个过程。我认为 expect 脚本是最简单的解决方案?然而我对这些不是很有经验。
#!/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
它似乎在第一次发送之前有效。然后卡住并等待输入? (错误的期望?)
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 "$ "
这是您遇到问题的部分:
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 命令的这种形式允许您同时查找多个字符串。如果看到的第一个是“(yes/no)?”,则发送 "yes" 并继续此 expect 命令。当看到"password:",发送密码,让expect命令结束。
您可能想要更改第二个生成命令 所以 shell 可以处理管道。
set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd
需要提供ip、用户名、密码作为命令行参数(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