Tcl 反斜杠替换不按我想象的方式工作

Tcl backslash substitution is not working the way I'd imagined

我无法找到一种方法来通过变量将模式(由 autoexpect 创建)作为模式提交给 expect 命令。

我的一个测试脚本的早期版本使用 autoexpect 脚本的手动编辑版本来自动测试应用程序,并且效果很好。不幸的是,它并不是完全可维护的,在应用程序发生变化后,我想我应该将测试分解为一系列交互,自动预期模式存储在一系列 ascii 文件中,然后 运行 一个过程来依次匹配每个片段。典型的片段如下所示(在 vi 中显示时):

run_db\r
\r
\r
\r

为了完整起见,这里是 hexdump 显示的相同片段:

0000000   r   u   n   _   d   b   \   r  \n   \   r  \n   \   r  \n   \
0000010   r  \n

因此,我的片段包含控制字符“\n”和转义序列“\”"r"(如果您明白我的意思!)

我的程序从我的 ascii 文件中读取这个字符串到一个变量中(我使用 "read -nonewline" 来这样做。)

然后我尝试 运行 期望反对模式:

expect {
   -gl "$pattern_string" { commands... 
   }
timeout { commands...
   }
}

但是,模式永远不会匹配!更奇怪的是,如果我将字符串本身直接替换为 expect 命令(而不是通过变量),则 expect 会完美匹配,只要我在每个“\r”之后插入一个“\n”:

expect {
   -gl "run_db\r\n\r\n\r\n\r\n" { commands... 
   }
timeout { commands...
   }
}

(我一点也不清楚为什么“\n”序列是必需的。它们不在 hexdump 中,所以我认为这 不应该 已匹配!)

我可能误解了替换。就好像我需要用 0x0a 替换“\”"r" 对,然后将变量替换到 expect 命令中。 (可能是在我的 autoexpect 文件的其他地方潜伏着其他转义字符。它相当大。)无论如何,我尝试匹配以下新变量但没有成功:

set substituted_pattern [ subst $pattern_string ]

非常感谢收到任何和所有建议... Allan。

我不太清楚 tcl 在各种情况下对反斜杠的解析,但根据经验,应该用真正的回车-return 替换两个字符 \r,因为这是您将从 expect 阅读中得到的。你可以这样做:

regsub -all {\r} $pattern_string "\r" pat2

将变量 pat2 设置为新版本。

字符序列 \r 被 glob 匹配器解释为匹配单个文字 r(反斜杠在这里不是很有用,但在与 glob 元字符一起使用时更有用,例如*?[)。您应该将字符串中的反斜杠加倍(即 \r)或使用精确匹配(-ex)。例如:

expect {
   -ex "$pattern_string" {
      commands... 
   }
   timeout {
      commands...
   }
}

也可以使用 string map:

处理字符串以使其与 glob 匹配一起工作
set processed_pattern [string map {{\r} {\r}} $pattern_string]
expect {
   -gl "$processed_pattern" {
      commands... 
   }
   timeout {
      commands...
   }
}