231 votes

Quelle est la différence entre les backticks de Perl, le système et l'exec?

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

260voto

Ludwig Weinzierl Points 6461

exec

exécute une commande et ne revient jamais. C'est comme un return déclaration d'une fonction.

Si la commande n'est pas trouvée exec renvoie la valeur false. Il ne revient jamais vrai, parce que si la commande est trouvé, il ne retourne jamais à tous. Il n'y a aucun point en revenant STDOUT, STDERR ou de sortie de statut de la commande. Vous pouvez trouver de la documentation à ce sujet en perlfunc, parce que c'est une fonction.

système

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

La valeur de retour est le statut de sortie de la commande. Vous pouvez trouver de la documentation à ce sujet en 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 la commande. qx// est équivalent à backticks. Vous pouvez trouver de la documentation à ce sujet en perlop, parce que contrairement à d' system et execc'est un opérateur.


D'autres moyens

Ce qui est manquant dans le ci-dessus est une façon d'exécuter une commande en mode asynchrone. Cela signifie que votre script perl et votre commande exécuter simultanément. Ceci peut être accompli avec open. Il vous permet de lire STDOUT/STDERR et écrire à l' STDIN de votre commande. Il est 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 sur windows.

165voto

Chas. Owens Points 40887

En général j'utilise system, open, IPC::Open2ou IPC::Open3 selon ce que je veux faire. L' qx// de l'opérateur, bien que simple, est trop contraignant dans sa fonctionnalité très utile en dehors de quick hacks. - Je trouver de l' open beaucoup plus maniable.

system: exécuter une commande et attendre le retour d'

Utiliser system lorsque vous souhaitez exécuter une commande, ne se soucie pas de son en sortie, et ne veulent pas le script Perl pour faire quelque chose jusqu'à ce que la commande est terminée.

#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écuter une commande et la capture de son STDOUT

Utiliser qx// lorsque vous souhaitez exécuter une commande, la capture de ce qu'il écrit sur la sortie standard, et ne veulent pas le script Perl pour faire quelque chose jusqu'à ce que la commande est 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: remplacer l'actuel processus avec un autre processus.

Utiliser exec avec fork lorsque vous souhaitez exécuter une commande, ne pas s'inquiéter à propos de sa sortie, et vous ne voulez pas 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 aussi consulter l' waitpid et perlipc manuels.

open: exécution d'un processus et de créer une pipe à son STDIN ou STDERR

Utiliser open lorsque vous souhaitez écrire des données dans un processus de STDIN ou lire des données à partir d'un processus STDOUT (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écuter un processus et de créer un canal à la fois l'entrée standard STDIN et STDOUT

Utiliser IPC::Open2 quand vous en avez besoin pour lire et écrire dans un processus de STDIN et STDOUT.

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écuter un processus et de créer un canal d'entrée standard STDIN, STDOUT, et STDERR

utiliser IPC::Open3 lorsque vous avez besoin pour capturer tous les trois descripteurs de fichiers du processus. Je voudrais écrire un exemple, mais il fonctionne essentiellement de la même façon IPC::Open2 fait, mais avec un ordre légèrement différent pour les arguments et un troisième descripteur de fichier.

17voto

bene Points 4294

Permettez-moi de citer les manuels d'abord:

perldoc exec():

La fonction exec exécute une commande système et ne retourne jamais-- utilisation d'un système au lieu de exec si vous voulez qu'il revienne

perldoc (système):

Fait exactement la même chose que exec LISTE , sauf qu' un fork est fait d'abord, et le processus parent attend pour le processus de l'enfant à compléter.

Contrairement à exec et système, backticks ne vous donne pas la valeur de retour, mais le collectées STDOUT.

perldoc `String`:

Une chaîne de caractères qui est (peut-être) par interpolation et puis exécuté en tant que système de commande avec /bin/sh ou son équivalent. Les caractères génériques du Shell, les pipes et redirections seront à l'honneur. Le collectées sortie standard de la commande est retournée; norme erreur n'est pas affectée.


Alternatives:

Dans des scénarios plus complexes, où vous voulez récupérer la sortie standard STDOUT, STDERR ou le code de retour, vous pouvez utiliser bien connu des modules standard comme IPC::Open2 et de 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 du CPAN est également intéressant de regarder...

2voto

Shane C. Mason Points 4074

La différence entre 'exec' et 'système' est que exec remplace votre programme actuel avec "commande" et à ne JAMAIS revenir à votre programme. système, d'autre part, de la fourche et de pistes de "commande" et vous renvoie le statut de sortie de "commande" lorsqu'il est fait en cours d'exécution. L'arrière cocher "commande", puis renvoie une chaîne de caractères représentant son standard (quel qu'il aurait imprimé à l'écran)

Vous pouvez également utiliser popen pour exécuter des commandes shell et je pense qu'il y a une coquille module 'utiliser le shell" qui vous donne accès transparent à l'environnement typique des commandes.

Espérons que le clarifie pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X