Quelqu'un peut-il m'aider? En Perl, quelle est la différence entre:
exec "command";
et
system("command");
et
print `command`;
Existe-t-il également d'autres façons d'exécuter des commandes shell?
Quelqu'un peut-il m'aider? En Perl, quelle est la différence entre:
exec "command";
et
system("command");
et
print `command`;
Existe-t-il également d'autres façons d'exécuter des commandes shell?
Réponses:
exécute une commande et ne revient jamais . C'est comme une returndéclaration dans une fonction.
Si la commande n'est pas trouvée, execrenvoie false. Il ne retourne jamais vrai, car si la commande est trouvée, elle ne revient jamais du tout. Il est également inutile de revenir STDOUT, STDERRou de l' état de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc, car il s'agit d'une fonction.
exécute une commande et votre script Perl se poursuit une fois la commande terminée.
La valeur de retour est l'état de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc.
comme systemexécute une commande et votre script perl se poursuit une fois la commande terminée.
Contrairement à systemla valeur de retour est STDOUTde la commande.
qx//équivaut à des backticks. Vous pouvez trouver de la documentation à ce sujet dans perlop, car contrairement à systemet execc'est 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. Cela peut être accompli avec open. Il vous permet de lire STDOUT/ STDERRécrire sur STDINvotre commande. Cela dépend de la plateforme.
Il existe également plusieurs modules qui peuvent faciliter ces tâches. Il y a IPC::Open2et IPC::Open3et IPC::Run, ainsi que
Win32::Process::Createsi vous êtes sous Windows.
En usage général I system, open, IPC::Open2ou en IPC::Open3fonction de ce que je veux faire. L' qx//opérateur, bien que simple, est trop contraignant dans sa fonctionnalité pour être très utile en dehors des hacks rapides. Je trouve openbeaucoup plus pratique.
system: exécutez une commande et attendez qu'elle revienneÀ utiliser systemlorsque 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 `` : exécutez une commande et capturez son STDOUTÀ utiliser qx//lorsque vous souhaitez exécuter une commande, capturer ce qu'elle écrit dans STDOUT et ne souhaitez pas que le script Perl fasse quoi que ce soit tant que la commande n'est pas terminée.
#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 actuel par un autre processus.À utiliser execavec forklorsque vous souhaitez exécuter une commande, ne vous souciez pas de sa sortie et ne voulez pas attendre qu'elle revienne. systemest 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 pouvez également lire les manuels waitpidet perlipc.
open: exécuter un processus et créer un canal vers son STDIN ou STDERRÀ utiliser openlorsque vous souhaitez écrire des données dans le STDIN d'un processus ou lire des données dans le 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: $!";
À utiliser IPC::Open2lorsque vous devez lire et écrire dans les STDIN et 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>;
à utiliser IPC::Open3lorsque vous devez capturer les trois descripteurs de fichiers standard du processus. J'écrirais un exemple, mais cela fonctionne principalement 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 revient jamais - utilisez system au lieu de exec si vous voulez qu'elle revienne
Fait exactement la même chose que exec LIST, sauf qu'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 caractères génériques, les tuyaux et les redirections de Shell 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 récupérer STDOUT, STDERR ou le code retour, vous pouvez utiliser des modules standard bien connus comme IPC :: Open2 et IPC :: Open3 .
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 from the CPAN mérite également 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`;
execexecexécute une commande et ne reprend jamais le script Perl. C'est à un script comme une returndéclaration est à une fonction.
Si la commande n'est pas trouvée, execrenvoie false. Il ne retourne jamais vrai, car si la commande est trouvée, elle ne revient jamais du tout. Il est également inutile de revenir STDOUT,STDERR ou de l' état de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc , car il s'agit d'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 print instructions, mais en raison de la execsortie du script, seule la première instruction print est exécutée. De plus, la execsortie de la commande n'est affectée à aucune variable.
Ici, vous n'obtenez que la sortie de la première printinstruction et de l'exécution de la lscommande en sortie standard.
systemsystemexécute une commande et votre script Perl reprend une fois la commande terminée. La valeur de retour est l'état 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 print instructions. Lorsque le script reprend après la systemcommande, les trois instructions d'impression sont exécutées.
En outre, le résultat de l'exécution system est affecté à data2, mais la valeur affectée est0 (le code de sortie de ls).
Ici, vous obtenez la sortie de la première printinstruction, puis celle de la lscommande, suivie des sorties des deux dernières printinstructions sur la sortie standard.
`)Par exemple system, placer une commande entre guillemets exécute cette commande et votre script Perl est repris une fois la commande terminée. Contrairement à system, la valeur de retour est STDOUTde la commande. qx//équivaut à des backticks. Vous pouvez trouver de la documentation à ce sujet dans perlop , car contrairement au système et exec, c'est 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 printinstructions et les trois sont en cours d'exécution. La sortie de lsne va pas être standardisée directement, mais affectée à la variable data2, puis imprimée par l'instruction d'impression finale.
La différence entre 'exec' et 'system' est que exec remplace votre programme actuel par 'command' et ne revient JAMAIS à votre programme. système, d'autre part, bifurque et exécute 'commande' et vous renvoie l'état de sortie de 'commande' lorsqu'il est terminé. La coche arrière exécute «commande», puis retourne une chaîne représentant sa sortie standard (quelle qu'elle soit imprimée à 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 aux commandes shell typiques.
J'espère que cela vous le clarifie.
use Shell;( search.cpan.org/dist/Shell/Shell.pm )? Il n'est pas largement installé, et il n'est pas applicable à la question, je pense ...