为什么我的期望脚本只回显命令没有运行?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我的期望脚本只回显命令没有运行?相关的知识,希望对你有一定的参考价值。

所以我试图自动化一些ssh进程。我有我期望的代码。但我希望代码只回显/提示命令。它实际上并不运行该命令。

#!/usr/bin/expect -f

set timeout 10
set usrnm "aaaaaa"
set pwd "pppppp"
set addr1 "xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
set addr2 "xxx.xxxx.xxxx.com"

spawn ssh $usrnm@$addr1

expect {

    "(yes/no)?" {send "yes
";exp_continue} 

    "password: " {send  "$pwd
"}

}


expect "*#"
send "ssh $usrnm@$addr2
"

expect {

    "(yes/no)?" {send "yes
";exp_continue} 

    "password:" {send  "$pwd
"}

}

expect "*#"

send "cd /tmp/myself/folder
"

expect "*#"

send "./run_engine.sh test.py
"

expect eof

#interact

所以,如果我这样做

expect my_expect.exp

它只是打印命令:

spawn ssh aaaaaa@xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no (10s later) ssh aaaaa@xxx.xxxx.xxxx.com (10s later) cd /tmp/amz337/COAFALV (10s later) ./run_engine.sh test.py (exit)

我的剧本出了什么问题?

答案

因为当变量被替换时,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。

稍后,当您连接到第二台机器时,您将插入到字符串中,因此不需要splat:

send "ssh $ssh_opts($addr2) $usrnm@$addr2
"

您可能希望捕获超时事件并中止脚本:

expect {
    timeout      {error "timed-out connecting to $addr1"}
    "(yes/no)?"  {send "yes
"; exp_continue} 
    "password: " {send  "$pwd
"}
}

在脚本结束时,在run_engine脚本完成后,您仍然连接到addr2,因此expect eof实际上不会在生成的进程上检测到eof。您将在10秒后超时,预期进程将退出。为了整洁,你应该:

send "./run_engine.sh test.py
"
expect "*#"
send "exit
"
# this prompt is from addr1
expect "*#"
send "exit
"
# _now_ the spawned ssh process will end
expect eof

如果您认为run_engine脚本需要的时间超过10秒,则应在发送该命令之前调整timeout变量。

此外,在开发expect脚本时,您应该打开调试:

exp_internal 1

谢谢将向您展示幕后发生的事情,特别是在查看您的模式是否匹配时。

以上是关于为什么我的期望脚本只回显命令没有运行?的主要内容,如果未能解决你的问题,请参考以下文章

回显命令中的锚标记

简单的 NMAKE 文件失败(1 个回显命令)

批处理命令echo回显命令

无法在 bash 脚本期望中发送长命令

带有条件回显的 Shell 脚本

批处理命令