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.
The getc
and sysread
functions in Chapter 3 of Programming Perl, and in perlfunc (1); the documentation for the Term::ReadKey module from CPAN; Recipe 15.8; Recipe 15.9