Expect优先匹配首个正则模式时跳过部分输出缓冲区问题排查
问题根因
Expect的匹配优先级规则为:当多个模式都能匹配当前缓冲区内容时,会优先选择命中文本长度最长的模式,若命中长度相同,才按书写顺序选择靠前的模式。同时匹配成功后,Expect会清空缓冲区中从开头到命中内容末尾的所有数据。
在你的场景中,最后一段缓冲区同时存在转义序列外的current_dir和位于它之后的\e]133;B\a转义序列:
- 转义序列的命中结束位置远晚于
current_dir的命中结束位置,会被Expect优先匹配 - 匹配转义序列成功后,缓冲区中包含
current_dir的所有前置内容都会被一同清空,导致永远触发不了第二个匹配规则,最终超时
解决方案
推荐两种可直接运行的修改方案:
方案1:合并正则匹配(最稳妥)
将转义序列和目标字符串合并为同一个正则的不同分支,确保优先匹配缓冲区中最早出现的内容,完全规避优先级问题:
#!/usr/bin/expect -f spawn -noecho zsh -li expect { -re {(\e]\d+;[^\a]*\a)|(current_dir)} { if {$expect_out(1,string) ne ""} { # 命中转义序列,过滤后继续等待 send_error "escape found: $expect_out(1,string)\n" exp_continue } else { # 命中转义序列外的current_dir send_error "prompt found: $expect_out(buffer)\n" } } timeout { exit 1 } }
该方案逻辑:如果最早出现的是转义序列就直接过滤继续等待,如果最早出现的是current_dir,说明它不在转义序列范围内,直接命中需求。
方案2:转义序列加行首锚定
限制转义序列规则仅匹配缓冲区开头的转义序列,避免后置的转义序列把前置的有效内容清空:
#!/usr/bin/expect -f spawn -noecho zsh -li expect { -re {^\e]\d+;[^\a]*\a} { send_error "escape found: $expect_out(0,string)\n" exp_continue } "current_dir" { send_error "prompt found: $expect_out(buffer)\n" } timeout { exit 1 } }
该方案逻辑:每次仅处理缓冲区最开头的转义序列,处理完成后继续匹配,如果缓冲区开头不是转义序列,就会直接匹配current_dir规则。
内容的提问来源于stack exchange,提问作者ericbn
相关产品推荐
相关产品推荐

