ActiveState Code

Recipe 68397: Raw Console Input on UNIX Platforms


Get those direct keystrokes here by leveraging the power of stty!

Tcl
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Helper procedure
proc stty args {
   eval [list exec /bin/stty <@/dev/tty] $args
}

proc yesOrNo {prompt} {
   # Save the current state; makes it easier to reset!
   set savedStty [stty -g]

   # Turn off echoing and turn on raw input
   stty -echo raw

   # Prompt!
   puts -nonewline "$prompt [Y/N] "
   flush stdout

   set answer ?

   # Get input as yes or no, or sound the terminal bell...
   while {1} {
      switch [string tolower [read stdin 1]] {
         y {set answer yes; puts YES; break}
         n {set answer no;  puts NO;  break}
         default {puts -nonewline \a; flush stdout}
      }
   }

   # Put things back as they were; this is IMPORTANT!
   stty $savedStty

   return $answer
}

# DEMO CODE!
if {[yesOrNo "Frobnicate the manglewurzel?"]} {
   frobnicate manglewurzel
}

Discussion

This works on Solaris, and probably does on other UNIX platforms though I can't be sure of that. It definitely does not work on Windows...

Uses (aside from the above) might include getting passwords (which just requires turning off echo) and asking any other question which can have a single-letter answer.

Comments

  1. 1. At 12:48 p.m. on 24 sep 2002, Asif Haswarey said:

    Solaris 5.7 tclsh8.0 fixes to the above script.

    1) The tty device in the "stty" proc does not work.
    
    proc stty's body should be:
    
    eval [list exec /bin/stty &lt; [exec /bin/tty]] $args
    
    In the original script:
    
    &lt;@/dev/tty
    
    does not work. It is supposed to be the result of /bin/tty, ie.
    
    /dev/pts/&lt;some number&gt;
    
    2) In proc yesOrNo the "[" and "]" should be escaped.
    
    The following line in proc yesOrNo:
    
    puts -nonewline "$prompt [Y/N] "
    
    should be:
    
    puts -nonewline "$prompt \[Y/N\] "
    

Sign in to comment