2010-06-04 18 views
6

Tengo un script que capte la entrada estándar:En Perl, ¿cómo determino si hay una entrada estándar presente?

&process_input 

sub process_input { 
    while(<STDIN>) { 
     $log_data .= $_; 
    } 
} 

Cuando ejecuto el script:

myscript.pl -param1=a -param2=b 

se queda bloqueado en esta subrutina. Todo funciona bien si lo hago:

echo "" | myscript.pl -param1=a -param2=b 

pregunta es ¿cómo puedo determinar si hasta tengo un estándar en lugar de origen? Hubiera pensado que while() devolvería falso y no se ejecutaría, pero supongo que en realidad está esperando que escriba algo en eso porque está 'atascado'.

+1

posible duplicado de [¿Cómo puedo saber si STDIN está conectado a un terminal en Perl?] (Http://stackoverflow.com/questions/528781/how-can-i-tell-if-stdin-is-connected -to-a-terminal-in-perl) – Ether

Respuesta

18

Lo que quiere hacer es verificar de dónde viene su STDIN (STanDard INput): otra aplicación o un terminal. En su caso, es la segunda opción, lo que provoca que una operación de lectura bloquee el proceso hasta que el usuario ingrese algo. Para una solución, vea How can I tell if STDIN is connected to a terminal in Perl?.

if (-t STDIN) { 
    # input attached to terminal and will probably ask user 
} else { 
    # input from other process 
} 

También hay IO::Interactive que podrían hacerlo mejor comprobación/más fiable.

+0

Gracias! Dado que el script también puede ser ejecutado por otra aplicación, podría hacer la opción -t. – EDJ

2

La declaración <STDIN> no regresa hasta que presiona "enter" en la consola. Si desea evitar esto, creo que puede usar IO::Handle para envolver STDIN, y llamar al $stdin->blocking(0) para habilitar IO sin bloqueo.

+2

El problema no es bloquear IO, sino que '' (que es equivalente a 'readline (* FILEHANDLE)') está buscando una línea de entrada. No volverá hasta que se encuentre un '\ n' (bueno, técnicamente una instancia del separador de registros de entrada' $/').No importa si el mango está bloqueando o no. Además, si usa 'IO :: Handle', puede simplemente usar sus métodos en los controles globales existentes:' STDIN-> blocking (0); ' – daotoad

1

Eso es normal. El uso estándar para las herramientas de Unix es usar STDIN si no se da ningún archivo de entrada como argumento. Trate cat, less, grep, etc. Todo depende de la persona que llama para proporcionar información, aunque sólo sea

tool < /dev/null 

I encarecidamente no se trata de determinar si la "entrada" está disponible, ya que introducirá problemas no importa cómo se logra esta. Específicamente, evite -t ya que es problemático falsificar un terminal cuando sea necesario. En cambio, confíe en una interfaz más convencional.

Si desea que no se pueda ingresar ninguna entrada a su herramienta, es extraño que use STDIN en primer lugar. Uno normalmente usaría un argumento opcional.

tool --foo file 
tool --foo <(echo "") 

Otra opción sería solicitar que el usuario le informe cuando no hay entrada.

tool --batch 

Con el fin de ayudarlo con los problemas de diseño de su interfaz, realmente ayudaría saber lo que hace su herramienta.

0

Su programa continuará cuando el usuario escriba Ctrl + D, el carácter del final del archivo.

Cuestiones relacionadas