Quelle est la différence entre les backticks de Perl, system et exec?

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 d'autres moyens d'exécuter des commandes shell?

213
demandé sur brian d foy 2009-04-29 01:47:53

5 réponses

Exec

Exécute une commande et renvoie jamais. C'est comme une instruction return dans une fonction.

Si la commande n'est pas trouvée exec renvoie false. Il ne retourne jamais true, car si la commande est trouvée, elle ne retourne jamais du tout. Il est également inutile de revenir STDOUT, STDERR ou quitter l'état de la commande. Vous pouvez trouver de la documentation à ce sujet dans perlfunc, parce que c'est un fonction.

Système

Exécute une commande et votre script Perl est poursuivi 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.

Backticks

Comme system exécute une commande et votre script perl est poursuivi après la commande est terminée.

Contrairement à d'system la valeur de retour est STDOUT de commande. qx// est équivalent à backticks. Vous pouvez trouver de la documentation à ce sujet dans perlop, parce que, contrairement system et exec, il est un opérateur.


D'Autres moyens

Ce qui manque à 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 écrire STDIN de votre commande. Il est cependant dépendant de la plate-forme.

Il y a aussi plusieurs modules qui peuvent faciliter cette tâche. Il est IPC::Open2 et IPC::Open3 et IPC::Run, ainsi que Win32::Process::Create si vous êtes sous windows.

245
répondu Ludwig Weinzierl 2012-02-23 01:24:43

, 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 hacks rapides. Je trouve open beaucoup plus pratique.

system: exécutez une commande et attendez qu'elle retourne

Utilisez system lorsque vous voulez exécuter une commande, ne vous souciez pas de sa sortie et ne voulez pas que le script Perl fasse quoi que ce soit avant la commande terminer.

#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

Utilisez qx// lorsque vous voulez exécuter une commande, capturez ce qu'elle écrit dans STDOUT et ne voulez 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: remplacez le processus actuel par un autre processus.

Utiliser exec avec fork lorsque vous souhaitez exécuter une commande, ne pas s'inquiéter à propos de sa sortie, et ne pas voulez attendre qu'il revienne. 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 pouvez également lire les waitpid et perlipc les manuels.

open: exécutez un processus et créez un tuyau vers son STDIN ou STDERR

Utilisez open lorsque vous voulez écrire des données dans le STDIN D'un processus ou lire des données à partir du 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: $!";

IPC:: Open2 : exécute un processus et crée un canal vers STDIN et STDOUT

Utilisez IPC::Open2 lorsque vous devez lire et écrire dans 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>;

IPC:: Open3 : exécute un processus et crée un tuyau vers STDIN, STDOUT et STDERR

Utilisez IPC::Open3 lorsque 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 handle de fichier.

155
répondu Chas. Owens 2011-03-21 15:36:51

Permettez-moi de citer les manuels d'abord:

Perldoc exec():

La fonction exec exécute une commande système et renvoie jamais-- utiliser système au lieu de exec si vous le souhaitez à renvoyer

Système Perldoc():

Fait exactement la même chose que exec LIST, sauf que un fork est fait en premier, et le processus parent attend que le processus enfant se termine.

Contrairement à exec et system, les backticks ne vous donnent pas la valeur de retour mais la sortie standard collectée.

Perldoc ' Chaîne`:

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 de Shell, les tuyaux et les redirections seront honorés. Le collectées sortie standard de la commande est retournée; l'erreur standard est pas affectée.


Alternatives:

Dans des scénarios plus complexes, où vous voulez récupérer STDOUT, STDERR ou le code de 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 à partir du CPAN vaut également la peine d'être regardé...

16
répondu Benedikt Waldvogel 2009-04-28 22:35:13

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 instruction return est à une fonction.

Si la commande n'est pas trouvée, exec renvoie false. Il ne retourne jamais true, car si la commande est trouvée, elle ne retourne jamais du tout. Il est également inutile de revenir STDOUT, STDERR ou quitter l'état de la commande. Vous pouvez trouver de la documentation sur il en perlfunc, parce que 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 en raison du fait que exec quitte 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, seulement, vous obtenez seulement la sortie de la première print instruction et de l'exécution de la ls commande standard.

system

system exécute une commande et votre Le script Perl est repris après la fin de la commande. 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 instructions print. Lorsque le script est repris après la commande system, les trois instructions print sont exécutées.

Aussi, le résultat de l'exécution system est attribué à data2, mais la valeur assigné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 sur standard out.

Backticks (`)

Comme system, enfermer une commande dans les backticks exécute cette commande et votre script Perl est repris une fois la commande terminée. Contrairement à system, la valeur de retour est STDOUT de la commande. qx// est équivalent à 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 instructions print et les trois sont en cours d'exécution. La sortie de ls ne va pas être standard directement, mais assignée à la variable data2 et ensuite imprimée par l'instruction d'impression finale.

5
répondu linuxtestside 2016-06-04 12:19:04

La différence entre 'exec' et 'system' est que exec remplace votre programme actuel par 'command' et ne retourne jamais à votre programme. le système, d'autre part, fourche et exécute 'command' et vous renvoie l'état de sortie de 'command' quand il est fait en cours d'exécution. La coche arrière exécute 'command', 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 aux commandes shell typiques.

J'espère que cela clarifie pour vous.

1
répondu Shane C. Mason 2009-04-28 22:01:48