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

Dear Monks

I would like to be able to capture keystrokes inside my perlscript (In this particular case any keystroke will terminate an endless loop)

Where can I read about this stuff ?

Thanks a lot
Luca

Replies are listed 'Best First'.
Re: howto capture a keystroke
by matze (Friar) on Mar 06, 2006 at 09:04 UTC
    I think the example in the synopsis of Term::Readkey is what you are looking for.
      Yep, thnx
Re: howto capture a keystroke
by polettix (Vicar) on Mar 06, 2006 at 11:44 UTC
    Just for sake of TMTOWTDI, you can also have a look at the -1 / -one_char option of IO::Prompt. But it's probably only Term::ReadKey ;)

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
Re: howto capture a keystroke
by liverpole (Monsignor) on Mar 06, 2006 at 16:59 UTC
    If you're on a Linux system and want to "roll your own", you might consider creating a subroutine to enter "raw" terminal mode, as in the following example.  The subroutine one_key creates a closure which, each time it's called, gets the next character, but without blocking.  When you're done, you can call the closure a final time with a zero argument to reset "cooked" mode (normal terminal).
    #!/usr/bin/perl -w # # Example of getting a single, non-blocking character in Linux. # # 060306 liverpole # # Strict use strict; use warnings; # Create a subroutine (closure) for capturing a key sub one_key { chomp(my $stty = `stty -g`); # Save 'cooked' mode t +ty `stty -icrnl -icanon -echo min 0 time 0`; # Begin raw mode sub { # Create a closure if (!$_[0]) { # If argument is zero +... system("stty $stty"); # restore 'cooked' m +ode } else { # Otherwise get and re +turn `dd bs=1 count=1 <&0 2>/dev/null`; # a single keystroke } }; } # Main program my $p_one_key = one_key(); while (1) { print ' ' x int(rand(20)), "*\n"; select(undef, undef, undef, 0.1); last if $p_one_key->(1); } $p_one_key->(0);

    @ARGV=split//,"/:L"; map{print substr crypt($_,ord pop),2,3}qw"PerlyouC READPIPE provides"
      If you have a while loop that is spinning and you don't want to prompt the user for any key to be pressed such as with <STDIN> but to silently break out when she hits ENTER key use the following 3 line function called "keystroke()" where $j variable will change from 0 to 1 when the ENTER key is pressed: while (true) { ... if (&keystroke == 1) { last; } ... } sub keystroke { $i = ''; vec($i, fileno(STDIN), 1) = 1; $j = select ($i, undef, undef, 0); }
        If you have a while loop that is spinning and you don't want to prompt the user for any key to be pressed such as with <STDIN> and you don't want to use Term:ReadKey module but to silently break out when she hits ENTER key use the following 3 line function called "keystroke()" where $j variable will change from 0 to 1 when the ENTER key is pressed:

        while (true) {
            ...
            if (&keystroke == 1) {
                last;
            }
            ...
        }

        sub keystroke {
            $i = '';
            vec($i, fileno(STDIN), 1) = 1;
            $j = select ($i, undef, undef, 0);
        }
Re: howto capture a keystroke
by Anonymous Monk on Sep 05, 2013 at 16:23 UTC

    The following works great in windows. Shows you what the keyboard produced, exits when you hit ENTER. Note that some keys (like arrows) produce multi-character sequences.

    #!/usr/bin/perl -w use strict; use Term::ReadKey; my $key; my $OrdKey; ReadMode 'raw'; do { $key = ReadKey(0); $OrdKey = ord($key); print "Key is $OrdKey\n"; } while ($OrdKey != 13); ReadMode 'restore';