You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TCL 8.3(思科设备)实现CLI定时输出遇输入终止的问题

问题描述

需要实现每秒向CLI输出信息,检测到用户输入时停止输出循环,避免脚本无限运行。当前脚本使用gets stdin后会阻塞定时输出,无法同时执行两个任务;临时用计数限制循环,但效果不佳。运行环境为思科设备上的TCL 8.3。

现有代码

namespace eval vars {
    # counter as failsave
    set counter 1
}
set stop 0

proc print_message {} {
    if {$::vars::counter == 50} {
        break
    }
    puts "Printing message..."
    incr ::vars::counter
    after 1000 print_message
}

# Start the message printing loop
print_message

# Check for user input
while {!$stop} {
  set input [gets stdin]
  if {$input == "x"} {
    set stop 1
  }
}
puts "Stopped printing messages"

临时方案运行示例

roPWB12#get lte history 50
  1  16.02.2023 14:24:22   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 20.4 dB       
 25  16.02.2023 14:24:46   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 15.8 dB (-4.6)
Press enter for another 50 measurements or enter new amount of repeats... 
 51  16.02.2023 14:34:23   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 21.2 dB (+5.4)
 58  16.02.2023 14:34:30   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 20.2 dB (-1.0)
Press enter for another 50 measurements or enter new amount of repeats... 100
101  16.02.2023 14:38:23   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 14.6 dB (-5.6)
140  16.02.2023 14:39:01   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 14.8 dB (+0.2)
184  16.02.2023 14:39:46   RSSI: -63 dB        RSRP: -92 dB        RSRQ: -7 dB        SNR: 13.8 dB (-1.0)
Press enter for another 100 measurements or enter new amount of repeats... 
201  20.02.2023 11:18:15   RSSI: -64 dB (-1)   RSRP: -97 dB (-5)   RSRQ: -7 dB        SNR: 12.6 dB (-1.2)
245  20.02.2023 11:18:58   RSSI: -64 dB        RSRP: -97 dB        RSRQ: -7 dB        SNR: 21.2 dB (+8.6)
289  20.02.2023 11:19:43   RSSI: -64 dB        RSRP: -97 dB        RSRQ: -7 dB        SNR: 17.8 dB (-3.4)
Press enter for another 100 measurements or enter new amount of repeats... 7
解决方案

原脚本的核心问题是gets stdin为阻塞调用,会暂停TCL事件循环,导致after调度的定时任务无法执行。要同时实现定时输出和输入检测,需采用非阻塞式输入监听结合事件循环的方式:

修改后代码

namespace eval app {
    set running 1
    set counter 0
}

proc print_message {} {
    if {!$::app::running} {
        return
    }
    puts "Printing message [incr ::app::counter]..."
    after 1000 print_message
}

proc handle_input {} {
    if {[gets stdin input] >= 0} {
        # 输入x时停止输出循环
        if {$input eq "x"} {
            set ::app::running 0
            puts "\nStopped printing messages"
            # 移除stdin监听,避免重复触发
            fileevent stdin readable {}
        } else {
            # 可扩展处理其他输入,如调整输出次数/间隔
            puts "\nReceived input: $input"
        }
    }
}

# 启动定时输出任务
print_message

# 设置非阻塞输入监听:当stdin有输入时自动调用handle_input
fileevent stdin readable handle_input

# 启动事件循环,保持脚本运行直到running变量改变
vwait ::app::running

关键说明

  1. 非阻塞输入监听:通过fileevent stdin readable handle_input实现,不会阻塞事件循环,定时任务可正常执行。
  2. 状态控制:用::app::running变量控制定时任务的启停,无需依赖计数限制。
  3. 事件循环维持:vwait ::app::running让脚本持续运行,直到用户输入触发状态变更。

内容的提问来源于Stack Exchange,提问作者Mario Jost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:25:31