0

我写了以下期望脚本:

/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 过程的嵌套吗?

4

1 回答 1

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"
于 2016-09-19T19:35:45.070 回答