Página 1 de 1

Ejecutar programas externos desde perl y ocultar la salida

NotaPublicado: 2005-06-18 02:23 @141
por Jokin
Hola a todos:
Soy nuevo en Perl y veo que tiene unas posibilidades impresionantes. He leido el mensaje de kidd que muestra cómo ejecutar programas externos a Perl con system().
Mi pregunta es: ¿Cómo es posible ocultar los cálculos intermedio y que no se vean en pantalla? Cuando ejecuto un programa se me llena la pantalla de datos intermedios y sin relevancia.

Muchas gracias por vuestra atención,
Jokin

NotaPublicado: 2005-06-19 12:08 @547
por kidd
Hola:

Lo que podrías hacer es atrapar el output en una variable usando comillas invertidas, en vez de la función system.


SALUDOS

Re:

NotaPublicado: 2005-06-24 04:20 @222
por pbellon
Hola,

creo que esto te funcionaría:

$command = "programa a ejecutar";
open(COMMAND,"$command |") or die (print "No se puede ejecutar el comando $command: $!");
while (<COMMAND>) {
#Aqui es donde escribe la salida por consola
print "$_";
}
close COMMAND or die (print "No se puede cerra el comando $command: $!");

Re: Ejecutar programas externos desde perl y ocultar la sali

NotaPublicado: 2005-07-24 20:14 @884
por explorer
Jokin escribiste:¿Cómo es posible ocultar los cálculos intermedio y que no se vean en pantalla? Cuando ejecuto un programa se me llena la pantalla de datos intermedios y sin relevancia.


La forma más sencilla es ejecutar el programa con el comando qx, pero sin utilizar su salida para nada. Por ejemplo:
Código: Seleccionar todo
    qx( ps aux );

El problema es si el programa genera salida en la salida de errores. La solución completa estaría en capturar tanto el STDOUT como el STDERR.

Yo, últimamente, estoy utilizando el módulo Sysadm::Install, en concreto la función tap:
Código: Seleccionar todo
my($stdout, $stderr, $exit_code) = tap("ps", "aux");

con lo que ya tengo control total.

Re: Ejecutar programas externos desde perl y ocultar la sali

NotaPublicado: 2005-07-25 12:03 @544
por Perl user
explorer escribiste:
Jokin escribiste:¿Cómo es posible ocultar los cálculos intermedio y que no se vean en pantalla? Cuando ejecuto un programa se me llena la pantalla de datos intermedios y sin relevancia.


La forma más sencilla es ejecutar el programa con el comando qx, pero sin utilizar su salida para nada. Por ejemplo:
Código: Seleccionar todo
    qx( ps aux );

El problema es si el programa genera salida en la salida de errores. La solución completa estaría en capturar tanto el STDOUT como el STDERR.

Yo, últimamente, estoy utilizando el módulo Sysadm::Install, en concreto la función tap:
Código: Seleccionar todo
my($stdout, $stderr, $exit_code) = tap("ps", "aux");

con lo que ya tengo control total.


Bueno creo que es importante hacer caso a lo que el autor inicial de la pregunta dice... a veces es necesario ignorar la salida de algún programa, y bueno, en lo personal creo que usar un módulo solo para eso ( como el caso de Sysadm-Install el cual no fué escrito solo para esa tarea ) es un poco exagerado, system() en su modalidad PROGRAM, LIST, es un claro y seguro método para realizar dicha tarea.

qx// y los backticks fueron hechos para capturar salida, ignorarla es como ignorar una alarma de incendios.

Saludos,

Re: Ejecutar programas externos desde perl y ocultar la sali

NotaPublicado: 2005-07-25 14:32 @647
por explorer
Perl user escribiste:Bueno creo que es importante hacer caso a lo que el autor inicial de la pregunta dice... a veces es necesario ignorar la salida de algún programa
Es lo que intentaba dar, una opción más para que se ignorara la salida.
Perl user escribiste: y bueno, en lo personal creo que usar un módulo solo para eso ( como el caso de Sysadm-Install el cual no fué escrito solo para esa tarea ) es un poco exagerado
Tienes razón. Cuando digo que yo lo utilizo es porque en un sólo programa puedo utilizar say, tap, slurp, blurt, mv, cp y mkd. Si sólo necesito hacer un print "\n", pues no cargo Sysadm::install para hacer un solo 'say'.
Perl user escribiste:system() en su modalidad PROGRAM, LIST, es un claro y seguro método para realizar dicha tarea.
Me temo que no. system ejecuta el programa externo, pero utiliza el STDIN y STDOUT del script perl original, por lo que si el programa arrancado por system genera salida, saldrá por el STDOUT del script. El usuario verá los cálculos intermedios.
Recomiendo la lectura del capítulo 16 del Perl Cookbook, que aconseja utilizar la función open (como indicaba antes pbellon) o el módulo IPC::Open3 (algo caduco y caótico en el uso).
Repito que aquí estamos para dar opciones. Cuantas más mejor, ¿no? Quizás me he pasado de listo diciendo a un novato lo que no tiene que hacer, y por lo tanto pido disculpas. El comando tap del Sysadm::Install utiliza open.
Perl user escribiste:qx// y los backticks fueron hechos para capturar salida, ignorarla es como ignorar una alarma de incendios.
Recuerda la cantidad de veces que los programadores de C, C++ y Java ponen el cast de (void) para ignorar la salida de las funciones. Pues aquí lo mismo. Si sabemos que no nos interesan para nada la salida de algo, mejor es no verla, quizás porque interfiere con la verdadera salida que queremos dar al usuario.
Y sí, a veces hay que ignorar las alarmas de incendio: en los simulacros de incendio :)
En cuanto a ignorar la salida de los backticks, en la receta 16.1 del perl Cookbook sí que dice algo de que a Perl no le gusta ignorar la salida. Al final, recomienda utilizar open.

Re: Ejecutar programas externos desde perl y ocultar la sali

NotaPublicado: 2005-07-25 15:13 @676
por Perl user
explorer escribiste:Me temo que no. system ejecuta el programa externo, pero utiliza el STDIN y STDOUT del script perl original, por lo que si el programa arrancado por system genera salida, saldrá por el STDOUT del script.

No realmente, no ejecuta sin antes hacer un fork, de esa manera pasan los file descriptors del parent process, y claro, si es un programa que tenga salida alguna ( en caso de tenerla ), se verá reflejada en el STDOUT/STDERR correspondiente. Y solo retornará al parent process el
estado de salida.
explorer escribiste: El usuario verá los cálculos intermedios.
Recomiendo la lectura del capítulo 16 del Perl Cookbook, que aconseja utilizar la función open (como indicaba antes pbellon) o el módulo IPC::Open3 (algo caduco y caótico en el uso).

Conozco perfectamente lo que dice el Cookbook, y entiendo perfectamente el uso de open. Pero creo que no viene al caso, si realmente quisieras hacerlo a un poquito de mas bajo nivel, usarías
la forma de PIPE de open, e ignorarías el FH. Pero para qué? hay maneras mas sencillas y directas de hacerlo. Y IPC::Open3 no tiene mucho que ver en la plática, no creo que interese conectar mas de 3 procesos, y aquí ya hablamos de Procesos como tal.
Yo atí te recomiendo simplemente leer perldoc perlopentut
explorer escribiste:Recuerda la cantidad de veces que los programadores de C, C++ y Java ponen el cast de (void) para ignorar la salida de las funciones. Pues aquí lo mismo. Si sabemos que no nos interesan para nada la salida de algo, mejor es no verla, quizás porque interfiere con la verdadera salida que queremos dar al usuario.

El casting no es necesario, a menos que programes en K&R C, ANSI C no necesita casting para void. Puedes ignorar el valor de retorno.
explorer escribiste:Y sí, a veces hay que ignorar las alarmas de incendio: en los simulacros de incendio :)

Sí, y eso es MUY mal estilo... para eso tenemos herramientas propias para cada tarea, desatornillar con un martillo suena una tarea un poco tonta.
Es como cuando un programador de Java estúpidamente ignora una excepción.
explorer escribiste:En cuanto a ignorar la salida de los backticks, en la receta 16.1 del perl Cookbook sí que dice algo de que a Perl no le gusta ignorar la salida. Al final, recomienda utilizar open.

Mi respuesta a esto también está en la parte de arriba y aparte que está fuera de contexto... no leíste bien mi respuesta al parecer.