Expect能否处理空字节?添加null匹配块后触发段错误
在Expect中有效处理零值字节的方法?
问题描述
《Exploring Expect》一书指出Expect可等待零值字节,但实际测试中,添加null匹配块的脚本会匹配空字符串并触发段错误。测试脚本如下:
#!/usr/bin/env expect remove_nulls 0 spawn bash stty raw -echo log_user 0 expect { -i $spawn_id "?" { send_user -- [set expect_out(0,string)] exp_continue } -i $tty_spawn_id "?" { send -- [set expect_out(0,string)] exp_continue } -i $spawn_id null { send_user -- "Detected null" exp_continue } } stty cooked echo
移除null匹配块时,脚本可正常模拟交互会话,但无法处理进程输出的nulls;添加该块后,脚本立即输出“Detected nullSegmentation fault: 11”。
解决方案
直接用null关键字匹配零值字节在部分Expect版本中存在bug,会触发段错误,更可靠的做法是使用二进制字节表示\x00来匹配,同时调整匹配顺序避免冲突:
修改后的测试脚本
#!/usr/bin/env expect remove_nulls 0 spawn bash stty raw -echo log_user 0 expect { # 优先匹配零值字节 -i $spawn_id "\x00" { send_user -- "Detected null byte\n" exp_continue } # 匹配spawn进程的其他任意单个字符 -i $spawn_id "?" { send_user -- [set expect_out(0,string)] exp_continue } # 处理终端输入并转发给spawn进程 -i $tty_spawn_id "?" { send -- [set expect_out(0,string)] exp_continue } } stty cooked echo
关键调整说明
- 用
\x00替代null关键字:\x00是零值字节的标准十六进制表示,Expect对这种二进制匹配的解析更稳定,不会出现和空字符串混淆或触发段错误的问题。 - 调整匹配顺序:把零值字节的匹配块放在最前面,确保它优先被捕获——如果放在
?匹配块之后,?会匹配包括零值字节在内的任意单个字符,导致零值字节的匹配永远不会触发。 - 添加换行符:在输出检测提示时加上
\n,避免提示信息和后续错误输出混在一起,提升可读性。
额外注意事项
- 确保
remove_nulls 0已正确设置,这个命令会禁止Expect自动过滤输入/输出中的零值字节,是处理nulls的前提。 - 部分老旧版本的Expect对二进制字节的支持可能有限,若仍有问题,建议升级到最新稳定版的Expect。
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

