【问题标题】:How do I create a timeout for user input in TCL?如何在 TCL 中为用户输入创建超时?
【发布时间】:2010-02-18 04:40:06
【问题描述】:

我有一个大型 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 个键作为输入(用户不需要按 enter)。然后它打印出一个响应。 if 语句只是为了演示如何根据上述代码做出决定。无论好坏,如果没有操作系统的“stty”支持,它就无法运行。

【问题讨论】:

  • package require Expect

标签: input timeout tcl


【解决方案1】:

有关简洁的解决方案,请参阅this wiki page 中间的 proc gets-with-timeout,但请注意

  1. 它的超时动作是{puts "Are you fall asleep?"; exit},你应该改成{set GetsInput "my default input"}
  2. 这取决于在 Tcl 事件循环中等待 - 这就是 vwait 所做的。嵌入式 Tcl 安装可能不允许事件循环工作,这取决于它的集成方式。

如果你不能让它工作,一个更粗略的方法就是:

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

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

【讨论】:

  • Colin,该 wiki 代码看起来就像我需要的那样运行(至少,另一个 Fedora 系统上的测试脚本可以运行)!我将在我的申请中试一试,然后回复您。
  • 我做了一些修改,但我得到了我需要的功能。我将其添加到我的问题中并将其标记为答案。真的,我正要放弃这个,直到我看到你的回复科林!!
猜你喜欢
  • 2014-01-04
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多