Se podría solucionar con select() o alarm(), pero... depende un poco del sistema operativo en que estés. ¿Cuál es?
En
perldoc -f getc tienes un ejemplo de cómo leer el teclado sin que el programa se pare.
Con select(), puedes indicar un tiempo de
timeout. Si pones 10 segundos, select() esperará por la entrada de texto durante ese tiempo. Pero, como se dice en
getc, eso no quiere decir que select() regrese cuando el usuario pulse cualquier tecla, si no solo cuando pulse además la tecla Entrar.
Una vez tuve que hacer algo parecido. Usé el módulo Curses, ya que permite mandar comandos a la terminal, para indicarle que funcione en modo no bloqueante, y de esa manera, puedo llamar a la función getch() (de Curses) para leer una sola pulsación del teclado, sin que el programa se tenga que parar o que el usuario tenga que pulsar la tecla Entrar.
Algo así:
Using perl Syntax Highlighting
use Curses;
# Inicialización de la pantalla
initscr(); # inicialización
noecho(); # no se ve lo que se escribe
cbreak(); # No buffer, el sistema captura señales de parada
nodelay(1); # getch() no es bloqueante
# En caso de parada brusca del programa
$SIG{INT} = sub { done("Ouch!") };
sub done {
endwin();
# resetty();
print "\n@_\n";
exit;
}
# Bucle principal
while (1) {
# si el usuario ha pulsado algo, lo leemos
while ( (my $key = getch()) ne ERR) { # usamos un bucle, por si pulso varias veces
done("Hasta la vista") if $key eq 'q' # en caso de pulsar la 'q', salimos
}
...; # resto del programa
# Ver teclado
my ($in, $out) = ('', ''); # canales de entrada y salida
vec($in,fileno(STDIN),1) = 1; # marcamos el bit del canal correspondiente a STDIN
# iniciamos un proceso de escucha durante un $lapso de tiempo, de tal manera que siempre estemos en múltiplo de
# minuto completo con el reloj del sistema. También volverá antes, en caso de que el usuario pulse algo
select($out = $in, undef, undef, $lapso - ($lapso == 60 ? (localtime)[0] : 0) ); # tiempo de espera o pulsación teclado
}
Coloreado en 0.007 segundos, usando
GeSHi 1.0.8.4
Más información en
perldoc -f select
perldoc -f alarm
perldoc -f getc
perldoc perlipc
perldoc Curses (en caso de estar instalado, claro)