2010-02-18 3 views
2

J'ai un grand script TCL qui, à des points demande à l'utilisateur des questions comme, "S'il vous plaît entrer votre choix: A, B ou C?"Comment créer un délai d'attente pour l'entrée utilisateur dans TCL?

L'utilisateur doit taper le caractère et appuyer sur "Entrée" pour continuer à écrire. Y at-il de toute façon je peux automatiser cela dans TCL? Quelque chose comme, si l'utilisateur ne saisit rien dans les 10 secondes, par défaut l'option A sera prise et le script continuera? J'ai regardé autour et il semble que la seule façon dont TCL accepte les entrées est avec la commande "gets" - mais cela bloque et ne continuera pas jusqu'à ce que l'utilisateur entre quelque chose. Y a-t-il autre chose que je peux utiliser?

Réponse: La réponse de

Colin est ce qui m'a finalement conduit à la réponse que je cherchais (avec un peu de googler). Pour les personnes intéressées ici est le code que je fini par utiliser,

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 

Ce que le ci-dessus est de poser une question et attendre 5 secondes pour un utilisateur appuyer sur la touche. Il acceptera seulement 1 clé comme entrée (l'utilisateur n'a pas besoin d'appuyer sur Entrée). Il imprime ensuite une réponse. La déclaration if est juste pour démontrer comment on pourrait prendre des décisions basées sur le code ci-dessus. Pour le meilleur ou pour le pire, il ne fonctionnera pas sans le support "stty" de votre système d'exploitation.

+0

'package require Expect' –

Répondre

3

Pour une solution élégante voir proc obtient-avec-temps mort au milieu de this wiki page, mais notez

  1. Son action sur délai d'attente est {puts "Are you fall asleep?"; exit} que vous devriez probablement changer pour {set GetsInput "my default input"}
  2. Cela dépend en attente dans la boucle d'événement Tcl - c'est ce que vwait fait. Une installation Tcl incorporée peut ne pas permettre à la boucle d'événements de fonctionner, selon la manière dont elle a été intégrée.

Si vous ne pouvez pas obtenir ce travail, une approche plus grossière serait juste:

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

Cela rend stdin non bloquant, écrit une invite, attend 10 secondes, puis lit une ligne de entrée si elle a été entrée, continue juste si rien n'a été entré. L'inconvénient est qu'il attend les 10 secondes complètes même si l'utilisateur tape leur entrée immédiatement.

+0

Colin, ce code wiki semble fonctionner comme je le souhaite (Au moins, le script de test sur un autre système Fedora fonctionne)! Je vais donner un coup de feu sur ma demande et revenir vers vous. – chronodekar

+0

Il m'a fallu quelques modifications, mais j'ai la fonctionnalité dont j'ai besoin. Je l'ajoute à ma question et marque cela comme la réponse. Vraiment, j'étais sur le point d'abandonner jusqu'à ce que j'ai vu votre réponse Colin !! – chronodekar

Questions connexes