如何让Expect脚本将exit命令发送给被测程序而非自身执行
问题根源
首先澄清一个误解:你的报错不是Expect自身执行了exit命令导致的。实际触发错误的逻辑是:
当你把exit作为标准输入发送给被测程序后,被测程序会执行自身的退出逻辑直接终止运行,此时你之前spawn创建的进程会话会被系统回收。后续循环继续执行expect "."和send操作时,找不到对应的有效会话ID,就抛出了spawn id exp4 not open的错误。
修复方案
你可以在循环中增加进程退出状态判断,检测到被测程序终止后直接跳出循环即可,修改后的代码如下:
#!/usr/bin/env expect if { [llength $argv] != 2 } { puts "expect tester.exp <executable> <test-case>" exit 1 } set executable [lindex $argv 0] set TEST [lindex $argv 1] set test_cmds [split $TEST "\n"] spawn ./$executable set timeout 0.05 foreach test_cmd $test_cmds { # 增加expect的多分支判断,处理eof和超时情况 expect { "." { # 匹配到输出再发送命令 send "$test_cmd\r" # 如果发送的是exit命令,发完直接跳出循环,避免后续无效操作 if {$test_cmd eq "exit"} { break } sleep 0.05 } eof { # 检测到被测程序已退出,直接跳出循环 break } timeout { # 超时也继续发送,可根据自己的需求调整逻辑 send "$test_cmd\r" sleep 0.05 } } } send_user "\r" exit 0
核心修改点说明
- 给
expect增加了多分支匹配逻辑,除了匹配正常输出.之外,额外增加了eof分支检测被测进程是否退出,检测到退出就直接终止循环,不再执行后续的send操作 - 增加了
exit命令的特殊判断,发送完exit后直接跳出循环,从根源避免后续无效操作 - 保留了timeout分支的兼容处理,避免被测程序输出不及时导致命令漏发
内容的提问来源于stack exchange,提问作者Joonyoung Gwak
相关产品推荐
相关产品推荐

