如何在 TCL 中为用户输入创建超时?
我有一个大型 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于一个简洁的解决方案,请参阅 此 wiki 页面 中间的 proc gets-with-timeout,但请注意
{puts“你睡着了吗?”; exit}
您可能应该将其更改为{set GetsInput "my default input"}
如果你不能让它工作,一个更粗略的方法就是:
这使 stdin 非阻塞,写入提示,等待 10 秒,然后读取一行输入(如果已输入),如果没有输入则继续进入。缺点是即使用户立即键入输入,它也会等待整整 10 秒。
For a neat solution see proc gets-with-timeout in the middle of this wiki page, but note
{puts "Are you fall asleep?"; exit}
which you should probably change to{set GetsInput "my default input"}
If you can't get this to work, a cruder approach would be just:
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.