Обычно я использую system
, open
, IPC::Open2
или IPC::Open3
в зависимости от того, что я хочу сделать. Оператор qx//
, хотя и прост, слишком ограничен в своей функциональности, чтобы быть очень полезным вне быстрых взломов. Я нахожу open
намного удобнее.
system
: запустить команду и дождаться ее возврата
Используйте system
, если вы хотите запустить команду, не заботитесь о ее выводе и не хотите, чтобы скрипт Perl делал что-либо до ее завершения.
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
или
#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//
или `` : запустить команду и перехватить ее STDOUT
Используйте qx//
, когда вы хотите запустить команду, перехватите то, что она пишет в STDOUT, и не хотите, чтобы скрипт Perl делал что-либо, пока команда не завершится.
#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
: заменить текущий процесс другим процессом.
Используйте exec
вместе с fork
, когда вы хотите запустить команду, не заботитесь о ее выводе и не хотите ждать ее возвращения. system
на самом деле просто
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
}
Вы также можете прочитать инструкции waitpid
и perlipc
.
open
: запустить процесс и создать канал для его STDIN или STDERR
Используйте open
, если вы хотите записать данные в STDIN процесса или прочитать данные из STDOUT процесса (но не одновременно в оба).
#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 : запустить процесс и создать канал для STDIN и STDOUT
Используйте IPC::Open2
, когда вам нужно читать и записывать в STDIN и 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 : запустить процесс и создать канал для STDIN, STDOUT и STDERR
используйте IPC::Open3
, когда вам нужно захватить все три стандартных файловых дескриптора процесса. Я бы написал пример, но он работает в основном так же, как IPC :: Open2, но с несколько другим порядком аргументов и дескриптором третьего файла.