Quelqu'un peut-il m'aider s'il vous plaît? En Perl, quelle est la différence entre:
exec "command";
et
system("command");
et
print `command`;
Existe-t-il d'autres façons d'exécuter des commandes Shell?
exécute une commande et ne retourne jamais . C'est comme une déclaration return
dans une fonction.
Si la commande est introuvable, exec
renvoie false. Il ne retourne jamais vrai, car si la commande est trouvée, elle ne retourne jamais du tout. Il est également inutile de renvoyer STDOUT
, STDERR
ou le statut de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc
, car c'est une fonction.
exécute une commande et votre script Perl est poursuivi une fois la commande terminée.
La valeur de retour est le statut de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc
.
comme system
exécute une commande et votre script Perl est poursuivi une fois la commande terminée.
Contrairement à system
, la valeur renvoyée est STDOUT
de la commande. qx//
est équivalent aux backticks. Vous pouvez trouver de la documentation à ce sujet dans perlop
, car contrairement à system
et exec
, il s'agit d'un opérateur.
Ce qui manque dans ce qui précède est un moyen d’exécuter une commande de manière asynchrone. Cela signifie que votre script Perl et votre commande s'exécutent simultanément. Ceci peut être accompli avec open
. Il vous permet de lire STDOUT
/STDERR
et d'écrire dans STDIN
de votre commande. Il dépend cependant de la plate-forme.
Plusieurs modules peuvent également faciliter ces tâches. Il y a IPC::Open2
et IPC::Open3
et IPC::Run
, ainsi que Win32::Process::Create
si vous êtes sur Windows.
En général, j'utilise system
, open
, IPC::Open2
ou IPC::Open3
en fonction de ce que je veux faire. L'opérateur qx//
, bien que simple, est trop contraignant dans ses fonctionnalités pour être très utile en dehors des attaques rapides. Je trouve open
beaucoup plus pratique.
system
: lancez une commande et attendez qu’elle revienneUtilisez system
lorsque vous souhaitez exécuter une commande, ne vous souciez pas de sa sortie et ne voulez pas que le script Perl fasse quoi que ce soit jusqu'à la fin de la commande.
#doesn't spawn a Shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
ou
#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//
ou `` : lancez une commande et capturez son STDOUTUtilisez qx//
lorsque vous souhaitez exécuter une commande, capturez ce qu'il écrit dans STDOUT et ne souhaitez pas que le script Perl fasse quoi que ce soit jusqu'à la fin de la commande.
#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
: remplace le processus en cours par un autre processus.Utilisez exec
avec fork
lorsque vous souhaitez exécuter une commande, ne vous souciez pas de sa sortie et ne voulez pas attendre qu'elle soit renvoyée. . system
est vraiment juste
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
}
Vous voudrez peut-être également lire les manuels waitpid
et perlipc
.
open
: exécuter un processus et créer un canal vers son STDIN ou STDERRUtilisez open
lorsque vous souhaitez écrire des données dans le STDIN d'un processus ou lire des données à partir de STDOUT d'un processus (mais pas les deux en même temps).
#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: $!";
Utilisez IPC::Open2
lorsque vous devez lire et écrire dans le STDIN et le STDOUT d'un processus.
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>;
utilisez IPC::Open3
lorsque vous devez capturer les trois descripteurs de fichier standard du processus. J'écrirais un exemple, mais cela fonctionne essentiellement de la même manière que IPC :: Open2, mais avec un ordre légèrement différent des arguments et un troisième descripteur de fichier.
La fonction exec exécute une commande système et ne renvoie jamais - utilise système au lieu de exec si tu veux qu'il revienne
Fait exactement la même chose que exec LIST, sauf que un fork est fait en premier et que le processus parent attend la fin du processus enfant.
Contrairement à exec et system, les backticks ne vous donnent pas la valeur de retour mais le STDOUT collecté.
Une chaîne qui est (éventuellement) interpolée puis exécutée en tant que commande système avec / bin/sh ou son équivalent. Les jokers, les pipes et les redirections seront honorés. La sortie standard collectée de la commande est renvoyée ; l'erreur standard n'est pas affectée.
Dans des scénarios plus complexes, où vous souhaitez extraire STDOUT, STDERR ou le code de retour, vous pouvez utiliser des modules standard bien connus tels que IPC :: Open2 et IPC :: Open .
Exemple:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
Enfin, IPC :: Run du CPAN vaut également la peine d’être examiné…
Quelle est la différence entre les backticks de Perl (`
), system
et exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
exécute une commande et ne reprend jamais le script Perl. C'est à un script comme une déclaration return
est à une fonction.
Si la commande n'est pas trouvée, exec
renvoie false. Il ne retourne jamais vrai, car si la commande est trouvée, elle ne retourne jamais du tout. Il est également inutile de renvoyer STDOUT
, STDERR
ou le statut de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc, car c'est une fonction.
Par exemple.:
#!/usr/bin/Perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
Dans le code ci-dessus, il y a trois instructions print
, mais étant donné que exec
a quitté le script, seule la première instruction print est exécutée. De plus, la sortie de la commande exec
n'est affectée à aucune variable.
Ici, vous obtenez uniquement le résultat de la première instruction print
et l'exécution de la commande ls
à la sortie standard.
system
system
exécute une commande et votre script Perl reprend après l'exécution de la commande. La valeur de retour est le statut de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc.
Par exemple.:
#!/usr/bin/Perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
Dans le code ci-dessus, il y a trois instructions print
. Lorsque le script reprend après la commande system
, les trois instructions d'impression sont exécutées.
De plus, le résultat de l'exécution de system
est attribué à data2
, mais la valeur affectée est 0
(le code de sortie de ls
).
Ici, vous obtenez la sortie de la première instruction print
, puis celle de la commande ls
, suivie des sorties des deux dernières instructions print
à la sortie standard.
`
)Comme system
, enfermer une commande dans des backticks exécute cette commande et votre script Perl reprend après la fin de la commande. Contrairement à system
, la valeur renvoyée est STDOUT
de la commande. qx//
est équivalent aux backticks. Vous pouvez trouver de la documentation à ce sujet dans perlop, car contrairement à system et à exec
, il s'agit d'un opérateur.
Par exemple.:
#!/usr/bin/Perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
Dans le code ci-dessus, il y a trois instructions print
et les trois sont en cours d'exécution. La sortie de ls
ne passe pas directement à la sortie standard, mais est affectée à la variable data2
puis imprimée avec l'instruction d'impression finale.
La différence entre 'exec' et 'system' est que exec remplace votre programme actuel par 'command' et ne retourne JAMAIS à votre programme. system, d'autre part, forks et exécute 'commande' et vous renvoie le statut de sortie de 'commande' une fois l'exécution terminée. La coche arrière exécute 'commande' puis renvoie une chaîne représentant sa sortie standard (tout ce qu'elle aurait imprimé à l'écran)
Vous pouvez également utiliser popen pour exécuter des commandes Shell et je pense qu’il existe un module Shell - "utiliser Shell" qui vous donne un accès transparent à des commandes Shell typiques.
J'espère que cela clarifie les choses pour vous.