提问人:Mario Jost 提问时间:2/20/2023 最后编辑:Mario Jost 更新时间:2/20/2023 访问量:41
如果检测到输入,则中断输出
interrupt output if input is detected
问:
我想每秒向 CLI 发送一次信息。为了防止脚本无限期运行,如果检测到用户输入,我希望输出循环停止。我有这样的东西:
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"
但这行不通。一旦我得到任何得到 stdin,脚本就会停止并且不再提供任何输出。现在,我运行了带有计数解决方法的脚本,但我对结果不满意。
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
忘了提:我正在思科设备上使用 TCL 8.3......
答:
1赞
Donal Fellows
2/20/2023
#1
检测是否有任何用户输入需要读取,需要使用非阻塞输入技术(否则代码将停止并无限期等待)。在普通的 Unix 平台上,它们对于终端(例如您在交互式远程登录时使用的终端)工作得很好。(我无法判断思科设备在这方面是否足够正常。虽然 8.3 现在已经很古老了,但下面的代码可能没问题:这取决于 Unix 文件描述符的工作方式,而且在很长一段时间内都没有有意义的改变。
# Set up; this is the critical bit
fconfigure stdin -blocking false
puts "Press Enter to halt the loop"
while true {
after 100; # I don't want a demonstration loop to run too free
puts "generating some output now [incr counter]"
# Check for a newline
if {[gets stdin line] >= 0 || ![fblocked stdin]} {
puts "time to stop"
break
}
}
按下或关闭与终端的连接将停止循环。Enter
按任意键(而不是 )还需要将终端配置为原始模式。这需要调用或使用 Tcl 8.7(将其作为内置功能)。在你的情况下,更容易不需要这样做。Enterstty
评论
0赞
Donal Fellows
2/20/2023
我不相信你的循环是正确的;柜台处理有些东西在我看来很可疑。
0赞
Mario Jost
2/21/2023
该脚本不会崩溃,这意味着 TCL8.3 可以理解所有命令,但遗憾的是,仍然存在相同的问题,即只有一个输出行。之后,脚本等待输入。
0赞
Donal Fellows
2/21/2023
那么它肯定不是处于非阻塞模式。你包括电话了吗?如果你这样做了,那么你就无法得到你想要的;使用非阻塞 I/O 是唯一的方法(鉴于我很确定您不能在 Cisco 系统上使用线程)。fconfigure
0赞
Mario Jost
2/22/2023
是的,我确保插入 fconfigure 部分。奇怪的是,它没有对我吠叫,所以它理解命令 -blocking false。是的,我坚持使用这个 10 多年的版本。思科从不费心更新此内容。他们只是每年宣布更多的云内容。谢谢你的帮助,希望这个解决方案能在未来帮助其他人。
0赞
Donal Fellows
2/22/2023
问题在于,虽然 Tcl 可以很容易地在文件描述符上设置标志,但如果操作系统忽略它们,那么我们就无能为力了。
评论