Expect脚本 - 自动密码

4

我正在尝试编写一个脚本,自动输入密码“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

看起来在第一次发送后它能够正常工作,但是之后就会卡住并等待输入?(期望值错误?)


“但是B在重新启动时会删除其存储空间”,这是预期的行为吗? - msw
另一个选择是使用SSH密钥,而不是将密码写入脚本。 - Channa
3个回答

4
这是您遇到困难的部分:
spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"

当您发送密码后,您需要等待30秒钟才能看到(是/否?)提示,但是如果您之前已连接到该计算机,可能不会出现此提示。您希望有条件地期望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命令结束。
您可能需要更改第二个spawn命令,以便shell可以处理管道。
set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd

0
需要将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


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 "$ "

使用你的脚本 - > Spawn id exp6 未打开 - TheCheatsrichter
确保远程端不存在 ~/.ssh 目录。 - mofoe
@TheCheatsrichter:这个解决了你的问题吗?如果没有,你找到了解决方法吗? - mofoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接