You want to read a single character from the keyboard. For instance, you've displayed a menu of one-character options, and you don't want to require the user to press Enter to make their selection.
Use the CPAN module Term::ReadKey to put the terminal into
cbreak
mode, read characters from STDIN, and then put the terminal back into its normal mode:
use Term::ReadKey;
ReadMode 'cbreak';
$key = ReadKey(0);
ReadMode 'normal';
Term::ReadKey can put the terminal into many modes -
cbreak
is just one of them.
cbreak
mode makes each character available to your program as it is typed (see
Example 15.1
). It also echoes the characters to the screen; see
Recipe 15.10
for an example of a mode that does not echo.
#!/usr/bin/perl -w
#
sascii - Show ASCII values for keypresses
use Term::ReadKey;
ReadMode('cbreak');
print "Press keys to see their ASCII values. Use Ctrl-C to quit.\n";
while (1) {
$char = ReadKey(0);
last unless defined $char;
printf(" Decimal: %d\tHex: %x\n", ord($char), ord($char));
}
ReadMode('normal');
Using
cbreak
mode doesn't prevent the terminal's device driver from interpreting end-of-file and flow-control characters. If you want to be able to read a real Ctrl-C (which normally sends a
SIGINT
to your process) or a Ctrl-D (which indicates end-of-file under Unix), you want to use
raw
mode.
An argument of
0
to
ReadKey
indicates that we want a normal read using
getc
. If no input is available, the program will pause until there is some. We can also pass
-1
to indicate a non-blocking read, or a number greater than
0
to indicate the number of seconds to wait for input to become available; fractional seconds are allowed. Non-blocking reads and timed-out reads return either
undef
when no input is available or a zero-length string on end of file.
Recent versions of Term::ReadKey also include limited support for non-Unix systems.