【问题标题】:Using nested spawn method in expect scripts在期望脚本中使用嵌套的 spawn 方法
【发布时间】:2016-09-19 13:14:51
【问题描述】:

我编写了以下期望脚本:

/usr/bin/expect<<EOF
set SERVER_HOSTNAME "$env(SERVER_HOSTNAME)"

set USERNAME "$env(USERNAME)"
set PASSWORD "$env(PASSWORD)"

set timeout -1

spawn ssh "$USERNAME@$SERVER_HOSTNAME"
expect  {
        "Host key verification failed." { spawn ssh-keygen -R "$SERVER_HOSTNAME"; expect "known_hosts.old"; send_user "Updated host key details."; exp_continue}
        "continue connecting (yes/no)" { send "yes\r"; expect "Permanently added"; exp_continue}
        "assword:" { send_user "Keygen details are correctly mapped for this server\n"}
        }
EOF

在这里,我希望如果在生成“ssh”进程时无法验证服务器的主机密钥,那么嵌套的生成进程“ssh-keygen -R”应该删除旧密钥。然后“ssh”进程应该尝试再次连接,以便可以添加对应于该服务器的新密钥。

但是这里,在执行之后:

send_user "Updated host key details."

方法,期望进程从这个脚本中退出。

我知道另一种方法是将这个期望调用分为两个步骤,如下所示:

 /usr/bin/expect<<EOF
set SERVER_HOSTNAME "$env(SERVER_HOSTNAME)"

set USERNAME "$env(USERNAME)"
set PASSWORD "$env(PASSWORD)"

set timeout -1

spawn ssh "$USERNAME@$SERVER_HOSTNAME"
expect  {
        "Host key verification failed." { spawn ssh-keygen -R "$SERVER_HOSTNAME"; expect "known_hosts.old"; send_user "Updated host key details."; exp_continue}            
        "continue connecting (yes/no)" { send "yes\r"; expect "Permanently added"; exp_continue}
       "assword:" { send_user "Keygen details are correctly mapped for this server\n"}
        }


spawn ssh "$USERNAME@$SERVER_HOSTNAME"
expect  {           
        "continue connecting (yes/no)" { send "yes\r"; expect "Permanently added"; exp_continue}
        "assword:" { send_user "Keygen details are correctly mapped for this server\n"}
        }

EOF    

但是我们有没有办法一次性执行这个期望调用。简而言之,我想知道,spawn进程的嵌套可以吗?

【问题讨论】:

    标签: ssh nested expect spawning


    【解决方案1】:

    空白对可维护代码大有帮助:您不需要在每行压缩这么多命令。

    spawn ssh "$USERNAME@$SERVER_HOSTNAME"
    expect {
        "Host key verification failed." {
            spawn ssh-keygen -R "$SERVER_HOSTNAME"
            expect "known_hosts.old"
            send_user "Updated host key details."
            exp_continue
        }
        "continue connecting (yes/no)" {
            send "yes\r"
            expect "Permanently added"
            exp_continue
        }
        "assword:" { 
            send_user "Keygen details are correctly mapped for this server\n"
        }
    }
    

    我这种情况,不需要和ssh-keygen交互,所以用exec简单调用

        "Host key verification failed." {
            exec ssh-keygen -R "$SERVER_HOSTNAME"
            puts "Updated host key details."
            exp_continue
        }
    

    如果你需要生成一些东西并与之交互,你需要知道有一个隐式变量spawn_id,它由spawn 创建,并由expect 和send 使用。在生成任何其他进程之前,您需要保存当前进程的 spawn_id。例如:

    spawn process1
    set ids(1) $spawn_id
    expect -i $ids(1) "some pattern"
    send -i $ids(1) "some string\r"
    
    spawn process2
    set ids(2) $spawn_id
    expect -i $ids(2) "some pattern from process2"
    send -i $ids(2) "some string to process2\r"
    

    【讨论】:

    • 如何在流程 2 之后使用 exp_continue。例如如果我想编写如下脚本: spawn ssh "$USERNAME@$SERVER_HOSTNAME" set ids(1) $spawn_id expect { "Host key verification failed." {spawn ssh-keygen -R "$SERVER_HOSTNAME";期待“known_hosts.old”; send_user "更新主机密钥详情。"; exp_continue -i $ids(1)} “继续连接(是/否)” { spawn $ScriptsDir/TestProcess;发送 -i $ids(1) "是\r";期望 -i $ids(1) "永久添加"; exp_continue -i $ids(1)} "assword:" { send_user "Keygen 详细信息已正确映射到此服务器\n"} } EOF
    • 在上述情况下,我收到以下错误消息:“用法:exp_continue [-continue_timer] 在执行“exp_continue -i (1)”时我已将 ids 数组初始化为:array set ids { 1 "" }
    • 这是由于您将期望代码混合到 shell 脚本中的方式。你注意到$ids(1) 是如何变成(1) 的吗?那是替换变量 before 期望开始的外壳。更改您的heredoc 以使用单引号,这样shell 就不会触及期望变量:` /usr/bin/expect
    • 我使用 exec 命令也如下: spawn ssh "$USERNAME@$SERVER_HOSTNAME" set ids(1) $spawn_id expect { "Host key verification failed." {exec ssh-keygen -R "$SERVER_HOSTNAME"; puts "更新了主机密钥详细信息。"; exp_continue} "继续连接(是/否)" { 发送 "是\r";期待“永久添加”; exp_continue} "assword:" { send_user "Keygen 详细信息已正确映射到此服务器\n"} } EOF
    • 我得到以下输出:/.ssh/known_hosts 已更新。原始内容保留为 /.ssh/known_hosts.old,同时执行“exec ssh-keygen -R“hostname””,从“expect {”Host key verification failed。”{exec ssh-keygen -R“hostname”中调用"; puts "Updated host key details."; exp_continue} "continue c..." 这里我希望期望脚本的第二个语句也应该执行,但没有发生:"continue connected (yes/no)" { send "yes\r"; 期待 "永久添加"; exp_continue} 我们有办法让它成为可能吗?
    猜你喜欢
    • 2017-09-02
    • 1970-01-01
    • 2015-11-01
    • 2012-03-26
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多