如果一切都失败了 tcl 脚本失败

if all else fails tcl script fails

我正在尝试制作一个脚本来将文件传输到另一台设备。因为我无法解释可能发生的每一个错误,所以我试图制造一个 if-all-else 失败的情况:

spawn scp filename login@ip:filename
expect "word:"
send "password"

expect {
    "100" {
        puts "success"
    } "\*" {
        puts "Failed"
    }
}

这总是 returns 一条失败消息,甚至不传输文件,因为这段代码:

spawn scp filename login@ip:filename
expect "word:"
send "password"

expect "100"
puts "success"

显示文件传输并打印成功消息。

我无法理解我在第一段代码中的 if-expect 语句有什么问题。

问题是因为 \*。反斜杠将由 Tcl 翻译,从而使 \* 单独变成 * 然后传递给 expect 作为

expect *

如您所知,* 匹配任何内容。这就像在说,"I don't care what's in the input buffer. Throw it away." 这个模式总是匹配的,即使那里什么也没有。 记住 * 匹配任何东西,空字符串是任何东西! 作为这种行为的必然结果,这个命令总是 returns 立即。它从不等待新数据的到来。它不必因为它匹配所有内容。

我不知道你为什么用*。假设,如果您打算匹配文字星号,则使用 \*.

字符串 \* 被 Tcl 翻译成 \*。然后模式匹配器将 \* 解释为匹配文字 * 的请求。

expect "*" ;# matches * and? and X and abc
expect "\*" ;# matches * and? and X and abc
expect "\*" ;# matches * but not? or X or abc

记住两条规则:

  1. Tcl 转换反斜杠序列。
  2. 模式匹配器将反斜线字符视为文字。

注:除了问题,还有一个观察。您将 expect 块称为 if-else 块。 它与 If-Else 块不同。

原因是,在传统的 if-else 块中,我们肯定知道至少有一个块将被执行。但是,在expect中,情况并非如此。它更像是单独的多个 if 块。