期待脚本 - 自动密码

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