in reply to howto capture a keystroke

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"

Replies are listed 'Best First'.
Re^2: howto capture a keystroke
by Anonymous Monk on May 17, 2009 at 00:10 UTC
    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);
      }
        Any chance of changing the ENTER key for something else (like Q or whatever)?