2016-09-19 50 views
0

我写了下面的expect脚本:在使用嵌套产卵方法期望脚本

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

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

set timeout -1 

spawn ssh "[email protected]$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 

在这里,我想,如果同时spawing“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 "[email protected]$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 "[email protected]$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  

但是,我们有办法在一个去执行该期望的呼叫。简而言之,我想知道,我们可以做产卵过程的嵌套吗?

回答

0

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

spawn ssh "[email protected]$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-凯基互动,所以使用exec简单地称之为

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

如果你需要生成的东西,与它进行交互,你需要要知道有一个隐含变量,由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" 
+0

如何在过程2后使用exp_continue。如果我想编写一个脚本如下: \t产卵SSH “$ USERNAME @ $ SERVER_HOSTNAME” \t集ID(1)$ spawn_id在 \t期待{ \t \t \t “主机密钥验证失败。” {spawn ssh-keygen -R“$ SERVER_HOSTNAME”;预计“known_hosts.old”; send_user“更新了主机密钥的详细信息。”; exp_continue -i $ ids(1)} \t \t \t“continue connecting(yes/no)”{spawn $ ScriptsDir/TestProcess; send -i $ ids(1)“yes \ r”;期望-i $ ids(1)“永久添加”; exp_continue -i $ IDS(1)} \t \t \t “assword:”{send_user “注册机细节正确映射此服务器\ n” 个} \t \t \t} \t –

+0

EOF在上述情况下,我得到以下错误消息: “用法:exp_continue [-continue_timer] 在执行 “exp_continue -i(1)” 我已初始化ids数组为: 阵列设置的ID {1 “”} –

+0

这是由于你的方式将预期代码混合到一个shell脚本中,你注意到'$ ids(1)'变成了'(1)'吗?在预期开始之前,用壳代替变量*。改变你的heredoc使用单引号,所以shell不会碰到expect变量:'/ usr/bin/expect <<'EOF'' –