2008-08-19 13 views
10

En Perl, puede ejecutar comandos del sistema usando system() o `` (barras). Incluso puede capturar la salida del comando en una variable. Sin embargo, esto oculta la ejecución del programa en segundo plano para que la persona que ejecuta el script no pueda verlo.¿Cómo puede el sistema de Perl() imprimir el comando que está ejecutando?

Normalmente esto es útil, pero a veces quiero ver lo que está sucediendo detrás de escena. ¿Cómo se hace para que los comandos ejecutados se impriman en el terminal y la salida de esos programas se imprima en el terminal? Este sería el equivalente .bat de "@echo on".

Respuesta

8

Según tengo entendido, system() imprimirá el resultado del comando, pero no lo asignará. P.ej.

[[email protected] /]$ perl -e '$ls = system("ls"); print "Result: $ls\n"' 
bin dev home lost+found misc net proc sbin  srv System tools var 
boot etc lib media  mnt opt root selinux sys tmp  usr 
Result: 0 

acentos abiertos capturará la salida del comando y no imprimirlo:

[[email protected] /]$ perl -e '$ls = `ls`; print "Result: $ls\n"' 
Result: bin 
boot 
dev 
etc 
home 
lib 

etc ...

Actualización: Si desea imprimir el nombre del comando siendo system() 'd también, creo que el enfoque de Rudd es bueno. Repite aquí para la consolidación:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 
4

En lugar de abrir, abra. Entonces puedes capturar la salida del comando.

open(LS,"|ls"); 
print LS; 
18

no sé de ningún modo por defecto para hacer esto, pero se puede definir una subrutina que lo haga por usted:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 

y luego ver en acción :

pbook:~/foo rudd$ perl foo.pl ls 
ls 
file1 file2 foo.pl 
2

Hmm, interesante cómo diferentes personas están respondiendo de esta manera diferente. Me parece que mk y Daniel Fone lo interpretaron como queriendo ver/manipular el stdout del comando (ninguna de sus soluciones captura stderr fwiw). Creo que se acercó Rudd. Una vuelta de tuerca que podrías hacer en la respuesta de Rudd es sobreescribir el comando incorporado en el sistema() con tu propia versión para que no tengas que volver a escribir el código existente para usar su comando execute().

usando su ejecución() Sub En el post de Rudd, que podría tener algo como esto en la parte superior de su código:

if ($DEBUG) { 
    *{"CORE::GLOBAL::system"} = \&{"main::execute"}; 
} 

creo que va a funcionar, pero tengo que admitir que este es el vudú y que ha sido un tiempo desde que escribí este código. Aquí está el código que escribí hace años para interceptar las llamadas al sistema en un (espacio de nombres llamando) local o nivel mundial en el tiempo de carga del módulo:

# importing into either the calling or global namespace _must_ be 
    # done from import(). Doing it elsewhere will not have desired results. 
    delete($opts{handle_system}); 
    if ($do_system) { 
    if ($do_system eq 'local') { 
     *{"$callpkg\::system"} = \&{"$_package\::system"}; 
    } else { 
     *{"CORE::GLOBAL::system"} = \&{"$_package\::system"}; 
    } 
    } 
+0

El gran problema de sustituir el comando global '' system' es que system' tiene un prototipo complejo que no puede ser replicado por el sistema prototipo especificado por el usuario. Como resultado, algunos códigos simplemente no funcionarán si reemplaza 'system' con su versión personalizada. – cjm

1

Otra técnica para combinar con los otros mencionados en las respuestas es utilizar el comando tee . Por ejemplo:

open(F, "ls | tee /dev/tty |"); 
while (<F>) { 
    print length($_), "\n"; 
} 
close(F); 

Esto tanto imprimir los archivos en el directorio actual (como consecuencia de tee /dev/tty) y también imprimir la longitud de cada nombre de archivo de leer.

4

He aquí una actualización ejecutar que se imprimirán los resultados y devolverlos:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    my $ret = `$cmd`; 
    print $ret; 
    return $ret; 
} 
Cuestiones relacionadas