Reputation: 126
I have written following expect script:
/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
Here I want that if the host key of a server can't be verified while spawing "ssh" process, then the nested spawn process "ssh-keygen -R" should remove old key. Then the "ssh" process should try to connect again so that new key can be added corresponding to that server.
But here, after the execution of:
send_user "Updated host key details."
method, expect process is exiting out from this script.
I know the alternative can be to divide this expect call into two steps, as follows:
/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
But do we have a way to execute this expect call in one go. In nutshell, I want to know, can we do the nesting of spawn process?
Upvotes: 0
Views: 3592
Reputation: 246774
Whitespace goes a long way toward maintainable code: you don't need to squish so many commands per line.
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"
}
}
I this case, you don't need to interact with ssh-keygen, so use exec
to simply call it
"Host key verification failed." {
exec ssh-keygen -R "$SERVER_HOSTNAME"
puts "Updated host key details."
exp_continue
}
If you need to spawn something and interact with it, you need to know that there is an implicit variable, spawn_id
, created by spawn, and used by expect and send. You'll need to save the spawn_id of the current process before you spawn any other process. For example:
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"
Upvotes: 1