Alguém por favor pode me ajudar? No Perl, qual é a diferença entre:
exec "command";
e
system("command");
e
print `command`;
Existem outras maneiras de executar comandos shell também?
Alguém por favor pode me ajudar? No Perl, qual é a diferença entre:
exec "command";
e
system("command");
e
print `command`;
Existem outras maneiras de executar comandos shell também?
Respostas:
executa um comando e nunca retorna . É como uma return
declaração em uma função.
Se o comando não for encontrado, exec
retornará false. Ele nunca retorna verdadeiro, porque se o comando for encontrado, ele nunca retornará. Também há nenhum ponto em voltar STDOUT
, STDERR
ou status de saída do comando. Você pode encontrar documentação sobre isso perlfunc
, porque é uma função.
executa um comando e seu script Perl continua após a conclusão do comando.
O valor de retorno é o status de saída do comando. Você pode encontrar documentação sobre isso em perlfunc
.
like system
executa um comando e seu script perl continua após a conclusão do comando.
Ao contrário system
do valor de retorno é STDOUT
do comando.
qx//
é equivalente a backticks. Você pode encontrar documentação sobre isso perlop
, porque diferente system
e exec
é um operador.
O que está faltando acima é uma maneira de executar um comando de forma assíncrona. Isso significa que seu script perl e seu comando são executados simultaneamente. Isso pode ser realizado com open
. Ele permite que você leia STDOUT
/ STDERR
escreva no STDIN
seu comando. Depende da plataforma.
Existem também vários módulos que podem facilitar essas tarefas. Existe IPC::Open2
e IPC::Open3
e IPC::Run
, assim como
Win32::Process::Create
se você estiver no Windows.
No uso geral I system
, open
, IPC::Open2
, ou IPC::Open3
dependendo do que eu quero fazer. O qx//
operador, embora simples, é muito restritivo em sua funcionalidade para ser muito útil fora de hacks rápidos. Eu acho open
muito mais prático.
system
: execute um comando e aguarde o retornoUse system
quando quiser executar um comando, não se importe com a saída e não queira que o script Perl faça nada até que o comando termine.
#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 `` : execute um comando e capture seu STDOUTUse qx//
quando quiser executar um comando, capture o que ele grava no STDOUT e não deseja que o script Perl faça nada até que o comando seja concluído.
#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
: substitua o processo atual por outro processo.Use exec
junto fork
quando quiser executar um comando, não se importe com a saída e não espere que ele retorne. system
é realmente apenas
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
}
Você também pode querer ler o waitpid
e perlipc
manuais.
open
: execute um processo e crie um canal para seu STDIN ou STDERRUse open
quando desejar gravar dados no STDIN de um processo ou ler dados do STDOUT de um processo (mas não os dois ao mesmo tempo).
#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: $!";
Use IPC::Open2
quando precisar ler e gravar em STDIN e STDOUT de um 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>;
use IPC::Open3
quando precisar capturar todos os três identificadores de arquivo padrão do processo. Eu escreveria um exemplo, mas funciona principalmente da mesma maneira que IPC :: Open2, mas com uma ordem ligeiramente diferente dos argumentos e um terceiro identificador de arquivo.
A função exec executa um comando do sistema e nunca retorna - use system em vez de exec se desejar que ele retorne
Faz exatamente a mesma coisa que o exec LIST, exceto que uma bifurcação é feita primeiro e o processo pai aguarda a conclusão do processo filho.
Ao contrário do exec e do sistema , os backticks não fornecem o valor de retorno, mas o STDOUT coletado.
Uma sequência que é (possivelmente) interpolada e depois executada como um comando do sistema com / bin / sh ou seu equivalente. Curingas, canais e redirecionamentos do Shell serão respeitados. A saída padrão coletada do comando é retornada ; erro padrão não é afetado.
Em cenários mais complexos, nos quais você deseja buscar STDOUT, STDERR ou o código de retorno, é possível usar módulos padrão conhecidos como IPC :: Open2 e IPC :: Open3 .
Exemplo:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
Por fim, vale a pena olhar o IPC :: Run from the CPAN…
Qual é a diferença entre os backticks de Perl ( `
) system
e exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
executa um comando e nunca retoma o script Perl. É para um script como uma return
declaração é para uma função.
Se o comando não for encontrado, exec
retorna false. Ele nunca retorna verdadeiro, porque se o comando for encontrado, ele nunca retornará. Também há nenhum ponto em voltar STDOUT
, STDERR
ou status de saída do comando. Você pode encontrar documentação sobre isso em perlfunc , porque é uma função.
Por exemplo:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
No código acima, existem três print
instruções, mas, devido à exec
saída do script, apenas a primeira instrução de impressão é executada. Além disso, a exec
saída do comando não está sendo atribuída a nenhuma variável.
Aqui, apenas você está obtendo a saída da primeira print
instrução e executando o ls
comando na saída padrão.
system
system
executa um comando e seu script Perl é retomado após a conclusão do comando. O valor de retorno é o status de saída do comando. Você pode encontrar documentação sobre isso em perlfunc .
Por exemplo:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
No código acima, há três print
instruções. Como o script é retomado após o system
comando, todas as três instruções de impressão são executadas.
Além disso, o resultado da execução system
é atribuído data2
, mas o valor atribuído é 0
(o código de saída de ls
).
Aqui, você obtém a saída da primeira print
instrução, depois a do ls
comando, seguida pelas saídas das duas últimas print
instruções na saída padrão.
`
)Por exemplo system
, incluir um comando nos backticks executa esse comando e seu script Perl é retomado após a conclusão do comando. Em contraste com system
, o valor de retorno é STDOUT
do comando. qx//
é equivalente a backticks. Você pode encontrar documentação sobre isso no perlop , porque diferente do sistema e exec
, é um operador.
Por exemplo:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
No código acima, há três print
instruções e todas as três estão sendo executadas. A saída de ls
não será padronizada diretamente, mas atribuída à variável data2
e depois impressa pela instrução final print.
A diferença entre 'exec' e 'system' é que exec substitui seu programa atual por 'command' e NUNCA retorna ao seu programa. O sistema, por outro lado, bifurca e executa 'command' e retorna o status de saída de 'command' quando terminar de executar. O back tick executa 'command' e, em seguida, retorna uma string que representa seu padrão (o que quer que fosse impresso na tela)
Você também pode usar o popen para executar comandos do shell e acho que existe um módulo shell - 'use shell' que fornece acesso transparente aos comandos típicos do shell.
Espero que esclareça isso para você.
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? Não é amplamente instalado, nem é aplicável à questão, eu acho ...