tags:

views:

336

answers:

2

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.

A: 

Have you considered Expect?

Maybe you can use select? Not sure if this is relevant but here goes, anyway: http://osr600doc.sco.com/en/man/html.TCL/select.TCL.html

Moron
Thats the first link that came when I googled for it. But aren't 'send' , 'expect' or 'spawn' external tools? I'm looking for something that is built-in with TCL.Small explanation: The TCL I'm working with is embedded into a larger application, so I don't think I can use external tools (But I haven't tried though).Also, I can't figure out that web-link you mention. It's all greek to me. :( (Sorry)
chronodekar
Expect is not external. It is usually included with most tcl installations (If I remember correctly). Just try typing expect on the command line and see what happens.
Moron
Perhaps your tcl install supports select?
Moron
Ok, I read through those pages and I'm trying out expect and select on a Fedora system. But these don't work,<code> file : hello.tcl #!/usr/bin/tclsh puts "We are going to expect hello:\n" select {stdin} {} {} 5 puts "You said hello !!" #################################</code>Result, ./hello.tcl We are going to expect hello: invalid command name "select" while executing "select {stdin} {} {} 5" (file "./hello.tcl" line 3)If I replace the "select" with "expect" I get similar issues.What am I doing wrong ?
chronodekar
The select command referred to here is part of the Tclx extension. If it's on your system you would do package require Tclx to load it. It's not likely to be part of an embedded Tcl installation though.
Colin Macleod
+3  A: 

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.

Colin Macleod
Colin, that wiki code looks like it functions the way I need it (At least, the test script on another Fedora system works)! I'm going to give it a shot on my application and get back to you on it.
chronodekar
It took me a few modifications, but I got the functionality I need. I'm adding it to my question and marking this as the answer. Really, I was about to give up on this until I saw your reply Colin !!
chronodekar