Потому что Tcl (и, следовательно, ожидаемо) не изменяет границы слова, когда переменные подставляются.Вы пытаетесь войти на хост с именем точно:
xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
пробелы и все.
Логически, не имеет смысла помещать опции ssh в переменную, которая содержит адрес.Могу я предложить:
set addr1 "xxx.cloud.xxx.com"
set addr2 "xxx.xxxx.xxxx.com"
set ssh_opts($addr1) {-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no}
set ssh_opts($addr2) {}
Тогда
spawn ssh {*}$ssh_opts($addr1) $usrnm@$addr1
Синтаксис {*}
- это оператор Tcl "splat", который разбивает слово с пробелами на отдельные слова.См. https://tcl.tk/man/tcl8.6/TclCmd/Tcl.htm правило № 5.
Позже, когда вы подключаетесь ко второму компьютеру, вы интерполируете в строку, поэтому разделение не требуется:
send "ssh $ssh_opts($addr2) $usrnm@$addr2\r"
Возможно, вы захотите перехватить события тайм-аута и прервать выполнение сценария:
expect {
timeout {error "timed-out connecting to $addr1"}
"(yes/no)?" {send "yes\r"; exp_continue}
"password: " {send "$pwd\r"}
}
В конце сценария, после завершения сценария run_engine, вы все еще подключены к addr2, поэтому expect eof
фактически не будетобнаружить eof на порожденном процессе.Время ожидания истечет через 10 секунд, и ожидаемый процесс завершится.Для удобства вы должны:
send "./run_engine.sh test.py\r"
expect "*#"
send "exit\r"
# this prompt is from addr1
expect "*#"
send "exit\r"
# _now_ the spawned ssh process will end
expect eof
Если вы считаете, что сценарий run_engine займет больше 10 секунд, вы должны отрегулировать переменную тайм-аута перед отправкой этой команды.
Кроме того, при разработкеожидайте сценарий, вы должны включить отладку:
exp_internal 1
Спасибо покажет вам, что происходит за кулисами, особенно когда дело доходит до соответствия ваших шаблонов.