【问题标题】:if all else fails tcl script fails如果一切都失败了 tcl 脚本失败
【发布时间】:2015-05-09 11:13:04
【问题描述】:

我正在尝试编写脚本以将文件传输到另一台设备。由于我无法解释可能发生的所有错误,因此我试图做出 if-all-else 失败的情况:

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

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

这总是返回一个失败的消息,甚至不传输文件,就像这段代码:

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

expect "100"
puts "success"

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

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

【问题讨论】:

  • 你能告诉我你为什么使用\*吗?你打算匹配文字美元符号吗?
  • 我认为它会像一个 if-else 语句一样,如果它匹配 100,它就会跳出来。否则,如果没有 100,则将其视为错误,因此将打印失败
  • @Dinesh * 被称为星号。 $ 是美元符号。
  • @Jerry:谢谢。现在更正了。

标签: tcl expect scp


【解决方案1】:

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

expect *

如您所知,* 匹配任何内容。这就像说,“我不在乎输入缓冲区中有什么。把它扔掉。” 这个模式总是匹配的,即使那里什么也没有。 记住* 可以匹配任何东西,而空字符串就是任何东西! 作为这种行为的必然结果,这个命令总是立即返回。它从不等待新数据到达。它不必如此,因为它匹配所有内容。

我不知道你为什么使用 *.假设,如果您的意图是匹配文字星号,则使用 \\*

字符串\\* 被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. 模式匹配器将反斜杠字符视为文字。

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

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

【讨论】:

  • 我的想法是,如果100 匹配,那么它将跳出expect 语句(类似于if-else 语句)。如何像 if else 语句一样配置它?
  • 正如我提到的,它不是if-else 块。顺便说一句,您对 else 块的期望是什么。 ?
  • 您可以使用timeout 而不是\*,作为故障安全方案。如果出现 100,它将打印“成功”。如果发生超时,它将打印“失败”。您可以将timeout 的值更改为set timeout 60。默认值为 10 秒。
  • 我的期望:如果显示 100(这将代表 100%),则文件已成功传输。如果出现除 100 以外的任何其他内容,则表示文件传输失败。因此它将打印失败消息
  • expect 实际上是一个“等到其中一个匹配或我们超时”块。这并没有真正映射到任何标准的结构化编程符号(尽管它相对接近并发逻辑系统可以做的一些事情)。
猜你喜欢
  • 1970-01-01
  • 2014-07-05
  • 2017-07-02
  • 2018-01-29
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多