2

我最近更新并重新格式化了我的 /etc/hosts 文件,并希望运行每个系统(大约 1000 个)以刷新我的 known_hosts 文件。我正在考虑使用期望脚本向 RSA 指纹问题发送“是”。很简单。但是,我知道其中一些系统对我来说是全新的,而且我的密码尚未设置。这产生了两种可能性:

  1. “是”被发送到 RSA 指纹问题,我已登录服务器。然后,我需要发送一个退出以关闭连接,然后再移动到下一个主机。或者...

  2. “是”被发送到 RSA 指纹问题,并提示我更新我的密码,从当前密码开始,然后输入两次新密码。密码更新到下一个主机后,连接将自动关闭。

我想我对期望中的“if/else”的概念有一个基本的了解,但是我不完全理解如何嵌套它们,如果有更好的方法,或者我一开始就完全脱离了基础.

这就是我现在所拥有的:

set file1 [open [lindex $argv 0] r]

set pw1 [exec cat /home/user/.pw1.txt]
set pw2 [exec cat /home/user/.pw2.txt]

while {[gets $file1 host] != -1} {

    puts $host
    spawn -noecho "ssh $host"
    expect {
        "continue connecting"{
            send "yes\r"
            expect {
                "current" {
                    send $pw2\r
                } "New password" {
                    send $pw1\r
                } "Retype new password" {
                    send $pw1\r
                }
            }
        expect "msnyder"
        send "exit\r"
    }
    interact
}

file1 变量是运行脚本的主机列表。

我知道它不准确,因为它在第 22 行出错。但是,我不知道需要修复什么。

4

2 回答 2

4

我发现了两个错误:

  1. 缺少右括号,可能是“继续连接”块
  2. “继续连接”的左大括号前缺少空格。Tcl(因此 Expect)对空格非常敏感,因为它在计算命令之前被解析为单词。对于极少数血淋淋的细节,请参阅Tcl 的 12 条语法规则

您的代码可能如下所示:

while {[gets $file1 host] != -1} {
    puts $host
    spawn -noecho "ssh $host"
    expect {
        "continue connecting" {
            send "yes\r"
            expect {
                "current" {
                    send -- $pw2\r
                    exp_continue
                } 
                "New password" {
                    send -- $pw1\r
                    exp_continue
                } 
                "Retype new password" {
                    send -- $pw1\r
                    exp_continue
                }
                msnyder
            }
            send "exit\r"
        }
    }
    interact
}

笔记:

  • exp_continue用于“循环”回到expect语句:在这种情况下,您将希望看到所有“当前”、“新”和“重新输入”,因此在看到提示之前您不想退出。
  • 养成打字的习惯send -- something。如果没有双破折号,当有人输入带有前导破折号的密码时,您会感到惊讶。
于 2013-09-06T15:31:35.090 回答
0

您可能可以避免让脚本像人类一样运行,而只是产生一个预期失败的 ssh 连接,该连接将自动接受主机 RSA 密钥,而无需提示输入密码;您可以稍后为需要启动密码的新系统执行此操作。

暂时尝试将其添加到您的 ~/.ssh/config 文件中,直到您的脚本完成:

Host *
  Protocol 2
  PasswordAuthentication 0
  StrictHostKeyChecking 'no'
  CheckHostIP 'no'
  UserKnownHostsFile ~/.ssh/known_hosts_new

然后,当新的 know_hosts_new 文件被加载时,您可以替换默认的 ~/.ssh/known_hosts 并从配置中删除 UserKnownHostsFile 行。

于 2013-09-06T03:19:10.820 回答