Expect脚本计时应用特定段异常:计时为0且输入未生效排查
问题排查与解决方案
核心问题原因分析
1. 输入匹配失败导致脚本提前终止
Expect脚本的核心是匹配目标程序的输出提示符来发送输入,如果timing.sh中的匹配模式和test.sh实际输出的提示不对应(比如大小写、空格、字符串差异),Expect会因为匹配超时直接退出,连带终止test.sh进程。此时test.sh还没执行到循环逻辑,计时自然为0,第二个输入也没机会发送。
2. 计时逻辑位置错误
如果计时代码(clock seconds的起止)没有包裹住循环执行的时间段,比如在发送输入后立即计算时间、没有等待循环执行完成,Expect会直接输出时间差(此时循环还没跑,时间差为0),然后退出。
3. 循环未被正确触发
若test.sh中循环的执行依赖第二个输入的正确触发(比如输入特定值才进入循环),而第一个输入失败导致程序流程未走到第二个输入节点,循环根本不会启动,计时结果必然为0。
输入问题修正与计时异常的关联
修正输入匹配问题不一定能直接解决计时异常,分两种情况:
- 如果计时异常是因为输入匹配失败导致
test.sh提前终止、循环未执行:修正匹配模式(让Expect正确捕获每个输入提示并发送输入)后,test.sh会正常走到循环逻辑,此时只要计时逻辑位置正确,就能得到正常的计时结果。 - 如果计时逻辑本身位置错误(比如把计时放在发送输入前,或者没等待循环完成就计算时间):即使输入问题解决了,计时结果还是会异常,需要同时调整计时代码的位置。
示例修正代码
假设test.sh的内容如下:
#!/bin/bash read -p "请输入第一个值: " val1 read -p "是否启动循环(y/n): " val2 if [ "$val2" = "y" ]; then echo "循环启动..." # 约5秒的循环 for i in {1..5}; do sleep 1 echo "循环步骤 $i" done echo "循环结束" fi
修正后的timing.sh(Expect脚本):
#!/usr/bin/expect spawn ./test.sh # 匹配第一个输入提示,发送输入 expect "请输入第一个值: " send "test_input\n" # 匹配第二个输入提示,发送触发循环的输入 expect "是否启动循环(y/n): " send "y\n" # 等待循环启动标记,此时开始计时 expect "循环启动..." set start_time [clock seconds] # 等待循环结束标记,此时停止计时 expect "循环结束" set end_time [clock seconds] # 输出计时结果 puts "循环耗时: [expr $end_time - $start_time] 秒" # 等待test.sh完全退出 expect eof
这个修正版本解决了输入匹配问题,同时将计时逻辑精准包裹在循环执行的时间段内,运行后会输出约5秒的耗时,第二个输入也能正常触发循环。
内容的提问来源于stack exchange,提问作者hacker_man_2021
相关产品推荐
相关产品推荐

