如何在TCL中为用户输入创建超时?

时间:2010-02-18 04:40:07

标签: input timeout tcl

我有一个大型的TCL脚本,在点上询问用户问题,“请输入您的选择:A,B或C?”

用户必须输入字符并按“Enter”继续编写脚本。无论如何我可以在TCL自动化吗?有些事情,如果用户在10秒内没有输入任何内容,默认情况下会选择A,脚本会继续吗?

我环顾四周,似乎TCL接受输入的唯一方法是使用“gets”命令 - 但这是阻止,并且在用户输入内容之前不会继续。还有什么我可以用的吗?

解答:

Colin的回复最终导致了我正在寻找的答案(以及一些谷歌搜索)。对于那些感兴趣的人是我最终使用的代码,

puts "Are you happy right now?"
puts "\(Press \"n\" or \"N\" within 5 seconds if you say \"No\"\)\nANSWER:"
global GetsInput
exec /bin/stty raw <@stdin
set id [after 5000 {set GetsInput "Y"}]
fileevent stdin readable {set GetsInput [read stdin 1]}
vwait ::GetsInput
after cancel $id
set raw_data $GetsInput
exec /bin/stty -raw <@stdin
uplevel #0 "unset GetsInput"
set user_input [string toupper $raw_data]

puts "\n"
if [ string equal $user_input "N"] {
    puts "You are making me upset as well!!\n"
} else {
    puts "I'm happy for you too !! (^_^)\n"
}

unset raw_data user_input

以上操作是问一个问题并等待用户按键5秒钟。它只接受1个键作为输入(用户不需要按回车键)。然后打印出响应。 if语句只是为了演示如何根据上述代码做出决策。无论好坏,如果没有操作系统的“stty”支持,它将无法运行。

1 个答案:

答案 0 :(得分:3)

对于一个简洁的解决方案,请参阅this wiki page中间的proc获取超时,但请注意

  1. 其对超时的操作是{puts "Are you fall asleep?"; exit},您应该将其更改为{set GetsInput "my default input"}
  2. 这取决于在Tcl事件循环中等待 - 这就是vwait的作用。嵌入式Tcl安装可能不允许事件循环工作,具体取决于它是如何集成的。
  3. 如果你不能让它工作,那么一个更粗略的方法就是:

    fconfigure stdin -blocking 0
    puts -nonewline "Enter data:"
    flush stdout
    after 10000
    gets stdin data
    puts "Got data '$data'"
    

    这使得stdin无阻塞,写入提示,等待10秒,然后读取输入行(如果已输入),如果没有输入则继续。缺点是,即使用户立即输入输入,它也会等待整整10秒。