[英]Conditions in Expect script causing it to hang
我正在使用期望脚本(在 bash 脚本中)到 ssh 到远程服务器并执行脚本,本地服务器将知道远程服务器的脚本已完成,因为它(远程)将在结尾处回显“完成”执行。
但是,该脚本可以位于三个位置之一,因此我设计了以下期望脚本,尽管在代码示例中它成功执行了远程服务器脚本 - 它无法检测到打印的“完成”并因此挂起。
本地服务器期望脚本:
versionScriptLoc1="/path/to/script1"
versionScriptLoc2="/path/to/script2"
versionScriptLoc3="/path/to/script3"
expect <<-EOS |& tee logfile.${hostname}.log
#!/usr/bin/expect
set timeout $EXP_TIMEOUT
puts "\nLogging into remote host via SSH..\n"
spawn ssh -q -tt -o ConnectTimeout=$SSH_TIMEOUT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${hostname}
expect "*assword*"
send -- "$secret\r"
expect {
"*assword*" {
send \x03
puts "\nIncorrect Password\n"
exit 1
}
"$prompt" {
send -- "/usr/seos/bin/sesu - $user\r"
expect "*assword*"
send -- "$secret\r"
expect "$prompt"
send -- "${versionScriptLoc1}\r"
expect {
"finished" {
}
"No such file or directory" {
puts "Location 1 execution Failed"
send -- "${versionScriptLoc2}\r"
expect {
"No such file or directory" {
puts "Location 2 execution Failed"
send -- "${versionScriptLoc3}\r"
}
}
exp_continue
}
}
send -- "exit\r"
expect "$prompt"
send -- "exit\r"
}
}
expect eof
exit 0
EOS
我认为 exp_continue 会进行预期循环并寻找“完成”。 在上面的代码中,脚本位于位置 2,它成功触发,但即使打印了“finished”,它仍然挂起。
任何关于它为什么挂起/可能是更好的设计的帮助将不胜感激。
PS:我知道我应该生成脚本而不是像用户一样触发它们,但我过去尝试过但没有成功。
我建议您不要将期望的代码编写得如此嵌套。
问题是,在运行 script2 之后,无论成功与否,都会点击 exp_continue。 太糟糕了 expect 没有exp_break
或goto
。
因此,需要进行一些重组。 我正在使用一些 boolean 变量来管理控制流。
由于我已经介绍了一些 Tcl 变量,因此将 shell 变量与 tcl 变量分开会更加困难。 我们将 shell 变量转换为环境变量,并引用 heredoc:
# ...
export EXP_TIMEOUT SSH_TIMEOUT
export hostname user secret prompt
export versionScriptLoc1 versionScriptLoc2 versionScriptLoc3
expect <<'EOS' 2>&1 | tee "logfile.${hostname}.log"
set timeout $env(EXP_TIMEOUT)
puts "\nLogging into remote host via SSH..\n"
spawn ssh -q -tt -o ConnectTimeout=$env(SSH_TIMEOUT) -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $env(hostname)
expect "*assword*"
send -- "$env(secret)\r"
expect {
"*assword*" {
send \x03
puts "\nIncorrect Password\n"
exit 1
}
"$env(prompt)"
}
send -- "/usr/seos/bin/sesu - $env(user)\r"
expect "*assword*"
send -- "$env(secret)\r"
expect "$env(prompt)"
set run2 false
send -- "$env(versionScriptLoc1)\r"
expect {
"No such file or directory" {
puts "Location 1 execution Failed"
set run2 true
}
"finished"
}
set run3 false
if {$run2} {
send -- "$env(versionScriptLoc2)\r"
expect {
"No such file or directory" {
puts "Location 2 execution Failed"
set run3 true
}
"finished"
}
}
if {$run3} {
send -- "$env(versionScriptLoc2)\r"
expect {
"No such file or directory" {
puts "Location 3 execution Failed"
}
"finished"
}
}
send -- "exit\r"
expect "$env(prompt)"
send -- "exit\r"
expect eof
exit 0
EOS
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.