我写了以下期望脚本:
/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”进程时无法验证服务器的主机密钥,那么嵌套的spawn进程“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
但我们是否有办法一次性执行此期望呼叫。简而言之,我想知道,我们可以进行生成过程的嵌套吗?
答案 0 :(得分: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创建的隐式变量spawn_id
,并由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"