在 TCL Expect 中,我是否需要转义$
才能将其用作锚点?例如,t
如果它出现在最后一个位置,则匹配应该是:
期望 t$
但这不起作用,我怀疑是因为 TCL 正在解释$
. 我尝试了以下所有方法均未成功
expect -re {t$}
expect t\$
expect t\\$
......但没有运气。帮助
当我在这里时,您如何匹配任何响应并捕获整个响应,即我怀疑类似以下内容
expect ^*$
但我$
的坏了。
正如 acheong87 所指出的,expect 脚本在响应中包含换行符。要查看这一点,请使用 glen jackman 提示并将 exp_internal 1 添加到脚本的顶部。因此,如果字符“t”在最后一个位置,则匹配字符“t”是:
expect -re {t\n$}
捕获任何响应和整个响应的一种方法是
expect -re {^.*.\n$}
在大多数情况下,您不必这样做,但请继续阅读。Expect 基本上是一个带有一些扩展的 TCL shell。TCL 使用美元符号 ($) 来执行变量替换当且仅当它在 TCL dodekalogue (http://wiki.tcl.tk/10259) 中描述的 3 个上下文之一中找到。简而言之,它们是 $name、${name} 和 $name(name) 形式。当 TCL 解释器处理您的脚本时,它不会替换美元符号,而是在不满足上述条件时将其保留在其文字形式中,例如
expect "abc\r\n$"
除非您使用大括号语法,否则不能使用以双引号开头或包含双引号的任何内容作为变量名。然而,无论如何通过反斜杠转义美元符号是明智的。
我要注意的是,在我的旧版本 Expect (5.25.0) 中,正则表达式处理器不执行反斜杠转义替换,因此如果您使用这样的版本,则不能使用大括号来转义换行符。在 Expect(TCL) 完成替换并且正则表达式匹配开始后,必须有一个文字换行符,这是通过让 Expect 替换 来实现的\n
。
因为Expect 的正则表达式不是面向行而是面向缓冲区的^
,$
分别表示缓冲区的开始和缓冲区的结束。
取决于终端的缓冲模式,Expect 可能只会逐行获取生成的进程的输出(就像在我的和大多数情况下一样),尽管没有换行符。
这保证(编辑:不是真的保证,见结尾)缓冲区的当前结束总是与生成进程的输出中的行结束一致。
另一个问题是(至少我的 UNIX 版本)Expect 与换行符不匹配\n
,而只匹配\r\n
!
即,它似乎将这两个字符放在它获取的每个输入块的末尾(编辑:实际上,替换了正常的换行符)。
因此,要匹配缓冲区末尾的字符 't',首先您必须确保在 't' 之后有一个终止换行符,并且生成的进程正在等待或以其他方式保证 Expect 的缓冲区不会被更多填充输入。
在 Expect 方面,正确的命令是:
expect -re "t\r\n\$" {...}
请注意,美元符号之前的反斜杠并不是真正需要的,我只是把它放在那里以支持这样做的好习惯。
编辑:当然,换行符确实被传递给 Expect,这与我最初写的相反,它似乎用“\r\n”代替。
我还想补充一点,我知道有一种情况是生成的进程的缓冲区被刷新,即当进程终止时。因此,实际上并不能保证新行的结尾是缓冲区的当前结尾,但在大多数情况下确实如此。
如果您尝试等待程序中的模式早于 Expect 脚本结束,您将获得该模式,结尾处没有任何换行符!
在这种情况下,您可以简单地匹配文本末尾的裸字符“t”
expect -re "t$" {...}