¿Alguien puede ayudarme? En Perl, ¿cuál es la diferencia entre:
exec "command";
y
system("command");
y
print `command`;
¿Hay otras formas de ejecutar comandos de shell también?
¿Alguien puede ayudarme? En Perl, ¿cuál es la diferencia entre:
exec "command";
y
system("command");
y
print `command`;
¿Hay otras formas de ejecutar comandos de shell también?
Respuestas:
ejecuta un comando y nunca regresa . Es como una return
declaración en una función.
Si no se encuentra el comando, exec
devuelve falso. Nunca devuelve verdadero, porque si se encuentra el comando, nunca regresa en absoluto. También hay ningún punto en la devolución STDOUT
, STDERR
o el estado de salida del comando. Puede encontrar documentación al respecto perlfunc
, porque es una función.
ejecuta un comando y su script Perl continúa después de que el comando ha finalizado.
El valor de retorno es el estado de salida del comando. Puede encontrar documentación al respecto en perlfunc
.
like system
ejecuta un comando y su script perl continúa después de que el comando ha finalizado.
Al contrario que system
el valor de retorno es STDOUT
del comando.
qx//
es equivalente a backticks. Puede encontrar documentación al respecto perlop
, porque a diferencia system
y exec
es un operador.
Lo que falta en lo anterior es una forma de ejecutar un comando de forma asincrónica. Eso significa que su script perl y su comando se ejecutan simultáneamente. Esto se puede lograr con open
. Le permite leer STDOUT
/ STDERR
escribir en STDIN
su comando. Sin embargo, depende de la plataforma.
También hay varios módulos que pueden facilitar esta tarea. Hay IPC::Open2
y IPC::Open3
y IPC::Run
, así como
Win32::Process::Create
si estás en Windows.
En el uso general I system
, open
, IPC::Open2
, o IPC::Open3
dependiendo de lo que yo quiero hacer. El qx//
operador, aunque simple, es demasiado restrictivo en su funcionalidad para ser muy útil fuera de los hacks rápidos. Me parece open
mucho más útil.
system
: ejecuta un comando y espera a que regreseÚselo system
cuando desee ejecutar un comando, no le importe su salida y no quiera que el script Perl haga nada hasta que finalice el comando.
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
o
#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");
qx//
o `` : ejecuta un comando y captura su STDOUTÚselo qx//
cuando desee ejecutar un comando, capture lo que escribe en STDOUT y no quiera que el script Perl haga nada hasta que finalice el comando.
#arguments are always processed by the shell
#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;
#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;
exec
: reemplaza el proceso actual con otro proceso.Úselo exec
junto con fork
cuando desee ejecutar un comando, no le importe su salida y no quiera esperar a que regrese. system
es realmente justo
sub my_system {
die "could not fork\n" unless defined(my $pid = fork);
return waitpid $pid, 0 if $pid; #parent waits for child
exec @_; #replace child with new process
}
También puede leer los manuales waitpid
y perlipc
.
open
: ejecuta un proceso y crea una tubería a su STDIN o STDERRÚselo open
cuando desee escribir datos en el STDIN de un proceso o leer datos del STDOUT de un proceso (pero no ambos al mismo tiempo).
#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
or die "could not open $filename: $!";
#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
or die "could not open $filename: $!";
Úselo IPC::Open2
cuando necesite leer y escribir en STDIN y STDOUT de un proceso.
use IPC::Open2;
open2 my $out, my $in, "/usr/bin/bc"
or die "could not run bc";
print $in "5+6\n";
my $answer = <$out>;
utilícelo IPC::Open3
cuando necesite capturar los tres identificadores de archivo estándar del proceso. Escribiría un ejemplo, pero funciona principalmente de la misma manera que IPC :: Open2, pero con un orden ligeramente diferente a los argumentos y un tercer identificador de archivo.
La función exec ejecuta un comando del sistema y nunca regresa ; use el sistema en lugar del exec si desea que regrese
Hace exactamente lo mismo que exec LIST, excepto que primero se realiza una bifurcación y el proceso padre espera a que se complete el proceso hijo.
A diferencia de exec y system , los backticks no le dan el valor de retorno sino el STDOUT recopilado.
Una cadena que (posiblemente) se interpola y luego se ejecuta como un comando del sistema con / bin / sh o su equivalente. Se respetarán los comodines de Shell, las tuberías y las redirecciones. Se devuelve la salida estándar recopilada del comando ; El error estándar no se ve afectado.
En escenarios más complejos, donde desea obtener STDOUT, STDERR o el código de retorno, puede usar módulos estándar bien conocidos como IPC :: Open2 e IPC :: Open3 .
Ejemplo:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
Finalmente, IPC :: Run from the CPAN también vale la pena mirar ...
¿Cuál es la diferencia entre los backticks de Perl ( `
) system
, y exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
ejecuta un comando y nunca reanuda el script de Perl. Es para un script como una return
declaración es para una función.
Si no se encuentra el comando, exec
devuelve falso. Nunca devuelve verdadero, porque si se encuentra el comando, nunca regresa en absoluto. También hay ningún punto en la devolución STDOUT
, STDERR
o el estado de salida del comando. Puede encontrar documentación al respecto en perlfunc , porque es una función.
P.ej:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
En el código anterior, hay tres print
declaraciones, pero al exec
abandonar el script, solo se ejecuta la primera declaración de impresión. Además, la exec
salida del comando no se asigna a ninguna variable.
Aquí, solo obtienes el resultado de la primera print
instrucción y de ejecutar el ls
comando en la salida estándar.
system
system
ejecuta un comando y su script Perl se reanuda una vez que el comando ha finalizado. El valor de retorno es el estado de salida del comando. Puede encontrar documentación al respecto en perlfunc .
P.ej:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
En el código anterior, hay tres print
declaraciones. A medida que se reanuda el script después del system
comando, se ejecutan las tres declaraciones de impresión.
Además, system
se asigna el resultado de la ejecución data2
, pero el valor asignado es 0
(el código de salida de ls
).
Aquí, obtienes el resultado de la primera print
instrucción, luego la del ls
comando, seguido de los resultados de las dos print
declaraciones finales en la salida estándar.
`
)Por ejemplo system
, al encerrar un comando en backticks se ejecuta ese comando y su script Perl se reanuda una vez que el comando ha finalizado. En contraste con system
, el valor de retorno es STDOUT
del comando. qx//
es equivalente a backticks. Puede encontrar documentación al respecto en perlop , porque a diferencia del sistema y exec
, es un operador.
P.ej:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
En el código anterior, hay tres print
declaraciones y las tres se están ejecutando. La salida de ls
no se va a estandarizar directamente, sino que se asigna a la variable data2
y luego se imprime mediante la declaración de impresión final.
La diferencia entre 'exec' y 'system' es que exec reemplaza su programa actual con 'command' y NUNCA regresa a su programa. sistema, por otro lado, bifurca y ejecuta 'comando' y le devuelve el estado de salida de 'comando' cuando termina de ejecutarse. La marca de retroceso ejecuta 'comando' y luego devuelve una cadena que representa su salida estándar (lo que sea que se haya impreso en la pantalla)
También puede usar popen para ejecutar comandos de shell y creo que hay un módulo de shell: 'use shell' que le brinda acceso transparente a los comandos de shell típicos.
Espero que eso te lo aclare.
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? No está ampliamente instalado, y tampoco es aplicable a la pregunta, creo ...