安装: Linux中的 Expect/Tcl脚本
用例:
使用expect等待在$user_command中使用某些状态的报表。
expect -re "notify (.+)\n"
set status $expect_out(1,string)
send [string map [list SESSION "$status"] "$user_command"]因此,当应用程序发送"notify running“时,status设置为running。为此,需要将$user_command中的关键字$status替换为$status,例如
"log STATUS to file"变成了
"log running to file"为了看看发生了什么,我写道
expect_tty -re "(.+)\n"
set status $expect_out(1,string)
send_user [string map [list SESSION "$status"] "$user_command"]它可以很好地独立运行。输出是
log someUserInput to file 键入someUserInput以响应expect_tty时。但是,作为更大脚本的一部分,它在替换字符串之前删除任何字符串映射命令,从而使输出变为
" to file" (没有换行符)我检查了脚本中变量的唯一性,因此这不是一个问题。
问题:
这里发生什么事情?如何使脚本变得健壮?
发布于 2021-03-02 14:56:50
感谢@glennjackman:
这个问题是由于应用程序将换行符报告为\r\n,所以(.*)\n在
expect_tty -re "(.+)\n" 匹配表达式1中的内容(括号中的内容)--在末尾包含\r。由于\r删除了之前的任何内容,string map似乎在替换字符串之前剪切任何内容。解决方案是期望一些不包括\r的东西,即
expect -re ``(\[^\r\n\]+)``它收集任何东西直到行结束,不管格式是什么。
发布于 2021-02-26 11:56:14
string map命令完全是确定性的。在其输入字符串的每个字符上,按顺序考虑映射列表中的任何from字符串是否匹配,如果匹配,则执行替换(使用配对字符串),并在替换后立即考虑该字符。(空字符串是一个特例:它永远不匹配。)实现它的代码非常愚蠢,但恰好在现代计算机上是非常友好的缓存,所以它仍然非常快;已经尝试过更复杂和“更快”的实现,但在野外常见的地图类型的实践中发现速度更慢。
如果替换失败,通常是因为输入字符串与您预期的不完全相同。在大多数程序中,这是很少见的,但在expect程序中比较常见,因为它们内部的终端仿真引擎的输出可以包括元字符,用于移动光标和更改颜色。(通常最简单的解决方法是告诉生成的程序,它的终端类型不支持如此复杂的特性,也许可以将TERM环境变量设置为dumb)。
https://stackoverflow.com/questions/66384159
复制相似问题