在expect脚本中使用if / else

时间:2013-09-06 01:39:22

标签: linux expect

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

  1. “是”发送到RSA指纹问题,我已登录 服务器。然后我需要发送一个退出来关闭连接 在进入下一个主机之前。或...

  2. “是”被发送到RSA指纹问题,我被提交 提示更新我的密码以当前和 然后输入两次新密码。连接会 密码更新后自动关闭移动到 下一位主持人。

  3. 我认为我对“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行出错。但是,我不知道需要修复什么。

2 个答案:

答案 0 :(得分:4)

我发现了两个错误:

  1. 缺少关闭括号,可能是“继续连接”块
  2. 在“继续连接”的开放式大括号之前缺少空格。 Tcl(因此Expect)对空格非常敏感,因为它在评估命令之前被解析为 words 。有关血腥的细节,请参阅12 syntax rules of Tcl
  3. 您的代码可能如下所示:

    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的习惯。没有双破折号,当有人输入带有前导破折号的密码时,你会感到惊讶。

答案 1 :(得分: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行。