Qualcuno può aiutarmi? In Perl, qual è la differenza tra:
exec "command";
e
system("command");
e
print `command`;
Ci sono altri modi per eseguire anche i comandi di shell?
Qualcuno può aiutarmi? In Perl, qual è la differenza tra:
exec "command";
e
system("command");
e
print `command`;
Ci sono altri modi per eseguire anche i comandi di shell?
Risposte:
esegue un comando e non ritorna mai . È come return
un'affermazione in una funzione.
Se il comando non viene trovato, exec
restituisce false. Non ritorna mai vero, perché se il comando viene trovato non ritorna mai affatto. V'è anche inutile tornare STDOUT
, STDERR
o lo stato di uscita del comando. Puoi trovare la documentazione a riguardo in perlfunc
, perché è una funzione.
esegue un comando e lo script Perl continua dopo il completamento del comando.
Il valore restituito è lo stato di uscita del comando. Puoi trovare la documentazione al riguardo in perlfunc
.
like system
esegue un comando e il tuo script perl continua dopo che il comando è terminato.
Al contrario system
del valore restituito è STDOUT
del comando.
qx//
equivale a backtick. Puoi trovare la documentazione a riguardo perlop
, perché a differenza di system
ed exec
è un operatore.
Ciò che manca da quanto sopra è un modo per eseguire un comando in modo asincrono. Ciò significa che lo script perl e il comando vengono eseguiti contemporaneamente. Questo può essere realizzato con open
. Ti permette di leggere STDOUT
/ STDERR
e scrivere sul STDIN
tuo comando. Tuttavia, dipende dalla piattaforma.
Esistono anche diversi moduli che possono facilitare queste attività. C'è IPC::Open2
e IPC::Open3
e IPC::Run
, così come
Win32::Process::Create
se sei su Windows.
In uso generale I system
, open
, IPC::Open2
, oppure IPC::Open3
a seconda di ciò che voglio fare. L' qx//
operatore, sebbene semplice, è troppo vincolante nella sua funzionalità per essere molto utile al di fuori di hack rapidi. Trovo open
molto più maneggevole.
system
: esegui un comando e attendi che ritorniUtilizzare system
quando si desidera eseguire un comando, non preoccuparsi del suo output e non si desidera che lo script Perl faccia nulla fino al termine del comando.
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
o
#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//
oppure `` : esegui un comando e acquisisci il suo STDOUTUtilizzare qx//
quando si desidera eseguire un comando, acquisire ciò che scrive su STDOUT e non si desidera che lo script Perl esegua alcuna operazione fino al termine del comando.
#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
: sostituisce il processo corrente con un altro processo.Utilizzare exec
insieme a fork
quando si desidera eseguire un comando, non preoccuparsi del suo output e non si desidera attendere che ritorni. system
è davvero giusto
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
}
Potresti anche voler leggere i manuali waitpid
e perlipc
.
open
: esegue un processo e crea una pipe nel suo STDIN o STDERRUtilizzare open
quando si desidera scrivere dati nello STDIN di un processo o leggere i dati dallo STDOUT di un processo (ma non entrambi contemporaneamente).
#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: $!";
Utilizzare IPC::Open2
quando è necessario leggere e scrivere su STDIN e STDOUT di un processo.
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>;
utilizzare IPC::Open3
quando è necessario acquisire tutti e tre gli handle di file standard del processo. Vorrei scrivere un esempio, ma funziona principalmente allo stesso modo di IPC :: Open2, ma con un ordine leggermente diverso rispetto agli argomenti e un terzo file gestito.
La funzione exec esegue un comando di sistema e non ritorna mai - usa il sistema invece di exec se vuoi che ritorni
Fa esattamente la stessa cosa di exec LIST, tranne per il fatto che un fork viene eseguito per primo e il processo parent attende il completamento del processo child.
Contrariamente a exec e system , i backtick non danno il valore di ritorno ma lo STDOUT raccolto.
Una stringa che è (possibilmente) interpolata e quindi eseguita come comando di sistema con / bin / sh o suo equivalente. I caratteri jolly Shell, i pipe e i reindirizzamenti verranno rispettati. Viene restituito l'output standard raccolto del comando ; l'errore standard non è interessato.
In scenari più complessi, in cui si desidera recuperare STDOUT, STDERR o il codice di ritorno, è possibile utilizzare moduli standard ben noti come IPC :: Open2 e IPC :: Open3 .
Esempio:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
Infine, vale la pena guardare anche IPC :: Run dal CPAN ...
Qual è la differenza tra i backtick di Perl ( `
) system
, e exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
esegue un comando e non riprende mai lo script Perl. È per uno script come return
un'istruzione è per una funzione.
Se il comando non viene trovato, exec
restituisce false. Non ritorna mai vero, perché se il comando viene trovato, non ritorna mai affatto. V'è anche inutile tornare STDOUT
, STDERR
o lo stato di uscita del comando. Puoi trovare la documentazione a riguardo in perlfunc , perché è una funzione.
Per esempio:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
Nel codice sopra, ci sono tre print
istruzioni, ma a causa di exec
lasciare lo script, viene eseguita solo la prima istruzione di stampa. Inoltre, l' exec
output del comando non viene assegnato a nessuna variabile.
Qui, solo tu stai ottenendo solo l'output della prima print
istruzione e l'esecuzione del ls
comando su standard out.
system
system
esegue un comando e il tuo script Perl viene ripreso al termine del comando. Il valore restituito è lo stato di uscita del comando. Puoi trovare la documentazione al riguardo in perlfunc .
Per esempio:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
Nel codice sopra, ci sono tre print
istruzioni. Quando lo script viene ripreso dopo il system
comando, vengono eseguite tutte e tre le istruzioni di stampa.
Inoltre, il risultato dell'esecuzione system
è assegnato a data2
, ma il valore assegnato è 0
(il codice di uscita da ls
).
Qui, stai ottenendo l'output della prima print
istruzione, quindi quello del ls
comando, seguito dagli output delle ultime due print
istruzioni sullo standard out.
`
)Ad esempio system
, racchiudendo un comando nei backtick viene eseguito quel comando e il tuo script Perl viene ripreso al termine del comando. Al contrario system
, il valore restituito è STDOUT
del comando. qx//
equivale a backtick. Puoi trovare la documentazione a riguardo in perlop , perché a differenza del sistema e exec
, è un operatore.
Per esempio:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
Nel codice sopra, ci sono tre print
istruzioni e tutte e tre sono in esecuzione. L'output di ls
non verrà standardizzato direttamente, ma assegnato alla variabile data2
e quindi stampato dall'istruzione di stampa finale.
La differenza tra 'exec' e 'system' è che exec sostituisce il tuo programma attuale con 'command' e MAI ritorna al tuo programma. il sistema, d'altra parte, esegue il fork ed esegue 'command' e restituisce lo stato di uscita di 'command' al termine dell'esecuzione. Il segno di spunta indietro esegue 'command' e quindi restituisce una stringa che rappresenta il suo standard out (qualunque cosa avrebbe stampato sullo schermo)
Puoi anche usare popen per eseguire i comandi della shell e penso che esista un modulo della shell: "usa la shell" che ti dà accesso trasparente ai tipici comandi della shell.
Spero che questo ti chiarisca.
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? Non è ampiamente installato, né applicabile alla domanda, penso ...