如何消除Expect脚本进程交互时产生的重复输出行?
问题分析与解决思路
问题根源
- Expect默认输出导致重复:Expect默认会将
spawn进程的所有输入(你send的内容)和输出都打印到终端,所以会出现「发送的内容+程序输出」的重复行。 - 正则表达式匹配错误:原正则
(\d+)\s*(\d+)试图匹配两个数字,但实际每个程序每次仅输出单个数字(一行),匹配逻辑混乱可能导致额外捕获不必要的内容。
解决步骤
1. 禁用Expect默认终端输出
在脚本开头添加log_user 0,关闭自动打印spawn进程的输入输出,之后完全手动控制需要打印的内容。
2. 修正正则表达式
将匹配规则改为捕获单个数字(兼容换行符),比如(\d+)\r?\n,确保每次仅捕获程序输出的一行有效数字。
3. 手动控制打印内容
在获取到程序的输出结果后,用puts命令仅打印必要的流程节点内容。
修改后的完整脚本
#!/usr/bin/env expect # 关闭默认输出,避免自动打印send内容和程序输出 log_user 0 spawn ./t2 set idt2 $spawn_id spawn ./t3 set idt3 $spawn_id # 初始输入1,手动打印初始值 send -i $idt2 "1\r" puts "1" expect { -i $idt2 -re {(\d+)\r?\n} { set q $expect_out(1,string) # 打印t2的计算结果 puts "$q" send -i $idt3 "$q\r" expect -i $idt3 -re {(\d+)\r?\n} set a $expect_out(1,string) # 打印t3的计算结果 puts "$a" send -i $idt2 "$a\r" exp_continue } -i $idt2 eof { exp_continue } -i $idt3 eof { } timeout { puts "超时: $expect_out(buffer)" } }
额外说明
log_user 0会关闭所有默认日志输出(包括spawn启动信息),让你完全掌控打印内容。- 正则
(\d+)\r?\n兼容类Unix和Windows的换行格式,确保稳定捕获程序输出的单行数字。 - 初始的
puts "1"是为了显示流程的起始输入,后续内容均从两个程序的计算结果中获取并打印。
内容的提问来源于stack exchange,提问作者Konstantin Vladimirov
相关产品推荐
相关产品推荐

