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?
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.
, 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.
Permettez-moi de citer les manuels d'abord:
La fonction exec exécute une commande système et renvoie jamais-- utiliser système au lieu de exec si vous le souhaitez à renvoyer
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.
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é...
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.
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.