退出 Expect 脚本

退出 Expect 脚本

我有这个expect脚本,它将登录主机,运行命令,返回其内容并退出。当我运行完命令后,需要进行什么样的清理/正确退出?这个命令总是会返回一些东西,我认为我应该处理的更大的问题或问题是 SSH 挂起,或者以管理员用户身份登录挂起。我想我可能已经通过 处理了这个问题timeout,但我不确定:

#!/usr/bin/expect -f

set timeout 10
match_max 100000
set hostname [lindex $argv 0]

spawn /usr/bin/ssh -o "StrictHostKeyChecking no" admin@$hostname
expect "*password:"
send -- "redactedSSHpassword\r"
expect "Username:"
send -- "admin\r"
expect "*password:"
send -- "redacted\r"
expect -- "*#*"
send -- "show stat summary\r"
expect -- "*#*"

我也不明白退出此脚本并确保我不会留下陈旧会话的正确方法。

答案1

如果超时,则expect语句将失败,它只会继续执行下一条语句。这可能没有意义,但它确实意味着类似以下的事情可能会发生。

You expect "Username:" and get it.
You send "admin\r", and get back "No such username"
You expect "password:" but don't get it because you got the "No such username" message, so you timeout.
You send "redacted\r" and get back "redacted: no such command" but redacted has been added to the history on the machine.
You expect "*#*" ....

当您的脚本到达末尾时,它将退出。此时,ssh 将被重新设置为 PID 1。ssh 将检测其标准输入上的 EOF,并将其传递并退出。所以你可能不需要任何额外的清理。

如果这是我的脚本我会写一个小程序

proc lookfor {pat} {
    expect timeout { send_user "timeout looking for '$pat'\r\n" ; exit } $pat
}

并将所有调用替换expect为 ,lookfor以便在匹配失败时立即退出。人们可以使用expect_afteror expect_beforebutlookfor进行简单的诊断。

答案2

互补伊卡洛斯的有用答案,您可以将其添加到您的 Expect 脚本的开头,以使其在任何超时时退出:

expect_before {
    timeout { puts "timeout"; exit 1 }
}

这将为每个expect命令添加给定处理程序的前缀。如果发生超时,它将打印“timeout”,然后退出,返回码为1

相关内容