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

发布于 2024-08-22 04:07:41 字数 1060 浏览 4 评论 0原文

我有一个大型 TCL 脚本,有时会询问用户问题,例如“请输入您的选择:A、B 或 C?”

用户必须输入字符并按“Enter”才能继续编写脚本。无论如何,我可以在 TCL 中自动执行此操作吗?比如,如果用户在 10 秒内没有输入任何内容,默认情况下将采用选项 A 并且脚本将继续?

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

答案:

科林的回复最终让我找到了我正在寻找的答案(以及一些谷歌搜索)。对于那些感兴趣的人来说,这是我最终使用的代码,

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”支持,它就无法运行。

I have a large TCL script that, at points asks the user questions like, "Please enter your choice : A, B or C ?"

The user has to type in the character and press "Enter" to continue to script. Is there anyway I can automate this in TCL? Something like, if the user doesn't enter anything within 10 seconds, by default option A will be taken and the script will continue?

I've looked around and it seems that the only way TCL accepts inputs is with the "gets" command - but this is blocking and won't proceed until the user enters something. Is there anything else I can use?

ANSWER:

Colin's reply is what ultimately led me to the answer I was looking for (along with a bit of googling). To those interested here is the code I ended up using,

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

What the above does is ask a question and wait for 5 seconds for a user key-press. It will accept ONLY 1 key as input (user doesn't need to press enter). It then prints out a response. The if statement is just to demonstrate how one could make decisions based on the above code. For better or worse, it won't run without "stty" support from your operating system.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

池木 2024-08-29 04:07:41

对于一个简洁的解决方案,请参阅 此 wiki 页面 中间的 proc gets-with-timeout,但请注意

  1. 它超时操作是{puts“你睡着了吗?”; 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'"

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

For a neat solution see proc gets-with-timeout in the middle of this wiki page, but note

  1. Its action on timeout is {puts "Are you fall asleep?"; exit} which you should probably change to {set GetsInput "my default input"}
  2. It depends on waiting in the Tcl event loop - that's what vwait does. An embedded Tcl installation might not allow the event loop to work, depending how it's been integrated.

If you can't get this to work, a cruder approach would be just:

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

This makes stdin non-blocking, writes a prompt, waits 10 seconds, then reads a line of input if it has been entered, just continuing if nothing has been entered. The downside is it waits the full 10 sec even if the user types their input immediately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文