strawberry logo lane historia example compilador perl

logo - En Perl, ¿cómo proceso la entrada tan pronto como llega, en lugar de esperar a la nueva línea?



perl vs python (5)

Desde perlfaq5: ¿Cómo puedo leer un solo carácter de un archivo? Desde el teclado? . Probablemente también quiera leer ¿Cómo puedo saber si hay un personaje esperando en un Filehandle? . Encuesta el Filehandle. Si hay un personaje allí, léelo y reinicia un temporizador. Si no hay personaje allí, inténtalo de nuevo. Si ha vuelto a intentar y pasado cierto tiempo, procese la entrada.

Después de leer los personajes, depende de usted decidir qué hacer con ellos. Con toda la flexibilidad de leer caracteres individuales, viene el trabajo extra de manejarlos.

Me gustaría ejecutar un subcomando de Perl (o convertirlo en una secuencia de comandos de Perl) y hacer que la secuencia de comandos procese la salida del comando de inmediato, en lugar de esperar un tiempo de espera, una nueva línea o una cierta cantidad de bloques. Por ejemplo, supongamos que quiero rodear cada fragmento de entrada con corchetes. Cuando ejecuto el script de esta manera:

$ ( echo -n foo ; sleep 5 ; echo -n bar ; sleep 5; echo baz) | my_script.pl

Me gustaría que la salida fuera así, con cada línea que aparece cinco segundos después de la anterior:

[foo] [bar] [baz]

¿Cómo puedo hacer eso?

Esto funciona, pero es realmente feo:

#! /usr/bin/perl -w use strict; use Fcntl; my $flags = ''''; fcntl(STDIN, F_GETFL, $flags); $flags |= O_NONBLOCK; fcntl(STDIN, F_SETFL, $flags); my $rin = ''''; vec($rin,fileno(STDIN),1) = 1; my $rout; while (1) { select($rout=$rin, undef, undef, undef); last if eof(); my $buffer = ''''; while (my $c = getc()) { $buffer .= $c; } print "[$buffer]/n"; }

¿Hay una forma más elegante de hacerlo?


No mencionó cómo está leyendo entrada en su script Perl, pero es posible que desee ver la función getc :

$|++; # set autoflush on output while ($c = getc(STDIN)) { print $c; }


Si hay tiempo entre cada personaje, es posible que pueda detectar las pausas.

Perl también hace entrada de línea: si no usas getc, deberías poder agregar nuevas líneas al final de foo, bar, etc. y perl te dará cada línea.

Si no puede agregar líneas nuevas, y no puede depender de una pausa, ¿qué espera exactamente que el sistema haga para decirle a Perl que ha comenzado un nuevo comando? En lo que respecta a perl, hay una tubería estándar, está consumiendo datos de ella, y no hay nada en la tubería estándar que le diga cuándo está ejecutando una nueva orden.

En su lugar, podría considerar lo siguiente:

$ echo "( echo -n foo ; sleep 5 ; echo -n bar ; sleep 5; echo baz)" | my_script.pl

o

$ my_script.pl$ "echo -n foo ; sleep 5 ; echo -n bar ; sleep 5; echo baz"

Y modifique su programa perl para analizar la "línea de comando" de entrada y ejecute cada tarea, comiendo el stdout según sea necesario.

-Adán



Term :: ReadKey puede hacer esto por usted. En particular, establezca el modo ReadKey () para realizar el sondeo por usted.

use Term::ReadKey; $| = 1; while( my $key = ReadKey(10) ) { print $key; }