Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Greetings: I've got a part in a script that's getting <STDIN> from the user, doing some processing, then looping. I've got it cut down to a menu, so the user only has to enter a number, and enter. (1-9 - all single digits). However, they have to do it a lot, so in hopes of this not getting to mundane, I'm wondering if there's a way I can have them enter their number, and go through the loop w/o hitting the enter key? Tx
  • Comment on get <STDIN> but don't require enter key

Replies are listed 'Best First'.
Re: get <STDIN> but don't require enter key
by revdiablo (Prior) on May 02, 2003 at 05:41 UTC

    You can use Term::ReadKey to do this. For example:

    use Term::ReadKey;
    
    ReadMode(3);
    my $key = ReadKey(0);
    ReadMode(0);
    
      Thanks. I downloaded the RPM, but am going through dependency hell. :( Kinda got busy here at work, but will play around w/ it in a bit. Thanks again
        To automatically grab dependencies, use CPAN.pm.
        perl -MCPAN -e 'install Term::ReadKey;'
        Should do the trick.
Re: get <STDIN> but don't require enter key
by jamesdmorris (Sexton) on May 02, 2003 at 17:21 UTC
    This works for me (Solaris 2.6, perl5.6.0):
    if ($BSD_STYLE) { system "stty cbreak </dev/tty >/dev/tty 2>&1"; } else { system "stty", '-icanon', 'eol', "\001"; } $key = getc(STDIN); if ($BSD_STYLE) { system "stty -cbreak </dev/tty >/dev/tty 2>&1"; } else { system "stty", 'icanon', 'eol', '^@'; # ASCII null } print "key was $key"; exit;
Re: get <STDIN> but don't require enter key
by mod_alex (Beadle) on May 03, 2003 at 13:14 UTC
    Hello

    Look at the FAQ Anywhay below is a solution from FAQ that works on a linux platform (and cygwin) only . Here is a module that provides all necessary methods. HotKey.pm

    package HotKey; @ISA = qw(Exporter); @EXPORT = qw(cbreak cooked readkey); use strict; use POSIX qw(:termios_h); my ($term, $oterm, $echo, $noecho, $fd_stdin); $fd_stdin = fileno(STDIN); $term = POSIX::Termios->new(); $term->getattr($fd_stdin); $oterm = $term->getlflag(); $echo = ECHO | ECHOK | ICANON; $noecho = $oterm & ~$echo; sub cbreak { $term->setlflag($noecho); # ok, so i don't want echo either $term->setcc(VTIME, 1); $term->setattr($fd_stdin, TCSANOW); } sub cooked { $term->setlflag($oterm); $term->setcc(VTIME, 0); $term->setattr($fd_stdin, TCSANOW); } sub readkey { my $key = ''; cbreak(); sysread(STDIN, $key, 1); cooked(); return $key; } END { cooked() } 1;
    and test program : test_key.pl
    #! /usr/bin/perl use HotKey; loop { $key = readkey(); print "you printed - $key \n"; } until $key eq 'a';
    Best regards Alex