Как мне создать тайм-аут для пользовательского ввода в TCL? - PullRequest
2 голосов
/ 18 февраля 2010

У меня есть большой скрипт TCL, который в точках задает пользователю такие вопросы, как «Пожалуйста, введите ваш выбор: A, B или C?»

Пользователь должен ввести символ и нажать «Enter», чтобы продолжить выполнение сценария. Есть ли в любом случае, я могу автоматизировать это в TCL? Примерно так: если пользователь ничего не вводит в течение 10 секунд, по умолчанию будет выбран вариант A и сценарий продолжится?

Я огляделся и, похоже, единственный способ, которым TCL принимает входные данные, - это команда «Get», но это блокировка, которая не будет продолжаться, пока пользователь не введет что-то. Могу ли я использовать что-нибудь еще?

ОТВЕТ:

Ответ Колина - это то, что в конечном итоге привело меня к ответу, который я искал (вместе с небольшим поиском в Google). Для тех, кто заинтересован, вот код, который я в итоге использовал,

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 Ответ

3 голосов
/ 18 февраля 2010

Для аккуратного решения см. Proc get-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'"

Это делает stdin неблокирующим, пишет приглашение, ждет 10 секунд, затем читает строку ввода, если она была введена, и просто продолжает, если ничего не было введено. Недостатком является то, что он ожидает полных 10 секунд, даже если пользователь вводит свои данные немедленно.

...