В чем разница между backticks Perl, system и exec?
может кто-то пожалуйста, помогите мне? В Perl, в чем разница между:
exec "command";
и
system("command");
и
print `command`;
есть ли другие способы запуска команд оболочки?
5 ответов
exec
выполняет команду и никогда не возвращает.
Это как return
оператор в функции.
если команда не найдена exec
возвращает false.
Он никогда не возвращает true, потому что если команда найдена, она никогда не возвращается вообще.
Также нет смысла возвращаться STDOUT
, STDERR
или состояние выхода команды.
Вы можете найти документацию об этом в perlfunc
,
потому что это функция.
система
выполняет команду, и ваш сценарий Perl продолжается после завершения команды.
возвращаемое значение - это состояние выхода команды.
Вы можете найти документацию об этом в perlfunc
.
backticks
как system
выполняет команду, и ваш скрипт perl продолжается после того, как команда законченный.
в отличие system
возвращаемое значение STDOUT
команды.
qx//
эквивалентно backticks.
Вы можете найти документацию об этом в perlop
, потому что в отличие от system
и exec
Это оператор.
другие способы
из вышесказанного отсутствует способ выполнения команды асинхронно.
Это означает, что ваш скрипт perl и ваша команда работать одновременно.
Это можно сделать с помощью open
.
Это позволяет читать STDOUT
/STDERR
и писать STDIN
вашей команды.
Однако это зависит от платформы.
есть также несколько модулей, которые могут облегчить эту задачу.
Есть IPC::Open2
и IPC::Open3
и IPC::Run
, а также
Win32::Process::Create
если вы находитесь в windows.
вообще пользуюсь system
, open
, IPC::Open2
или IPC::Open3
в зависимости от того, что я хочу сделать. The 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, но с немного другим порядком аргументов и третьим дескриптором файла.
позвольте мне сначала процитировать руководства:
функция exec выполняет системную команду и никогда не возвращает-- use система вместо exec если вы хотите вернуть
делает то же самое , что и exec LIST, за исключением того, что вилка делается во-первых, и родительский процесс ждет, пока дочерний процесс, чтобы закончить.
В отличие от exec и система, backticks не дают вам возвращаемое значение, но собранный STDOUT.
строка, которая (возможно) интерполируется, а затем выполняется как системная команда с / bin / sh или его эквивалент. Shell подстановочные знаки, трубы и перенаправления будут соблюдены. Собранные возвращается стандартный вывод команды; Стандартная ошибка остается без изменений.
варианты:
в более сложных сценариях, где вы хотите получить STDOUT, STDERR или код возврата, вы можете использовать хорошо известные стандартные модули, такие как IPC:: Open2 и IPC:: Open3.
пример:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
наконец, IPC:: Run из CPAN также стоит посмотреть на...
в чем разница между backticks Perl (`
),system
и exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
выполняет команду и никогда не возобновляет скрипт на Perl. Это к сценарию, как return
утверждение функция.
если команда не найдена, exec
возвращает false. Он никогда не возвращает true, потому что если команда найдена, она никогда не возвращается вообще. Также нет смысла возвращаться STDOUT
, STDERR
или выход состояние команды. Вы можете найти документацию об этом в perlfunc, потому что это функция.
Е. Г.:
#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";
в приведенном выше коде, есть три print
заявления, но из-за exec
оставляя скрипт, выполняется только первый оператор печати. Кроме того,exec
вывод команды не назначается ни одной переменной.
здесь, только вы получаете только выход первого print
утверждение и выполнение ls
команда на стандарт вне.
system
system
выполняет команду, и ваш скрипт Perl возобновляется после завершения команды. Возвращаемое значение-это состояние выхода команды. Вы можете найти документацию об этом в perlfunc.
Е. Г.:
#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";
в приведенном выше коде, есть три print
заявления. Как скрипт возобновляется после system
команда, все три оператора печати выполненный.
кроме того, результат выполнения system
is назначена data2
, но присвоенное значение 0
(код выхода из ls
).
здесь вы получаете выход первого print
заявление, затем заявление ls
команда, за которой следуют выходы последних двух print
заявления по стандарту out.
backticks (`
)
как system
, заключая команду в backticks выполняет, что команда и сценарий Perl возобновляются после завершения команды. В отличие от system
возвращаемое значение STDOUT
команды. qx//
эквивалентно backticks. Вы можете найти документацию об этом в perlop, потому что в отличие от системы и exec
, это оператор.
Е. Г.:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
в приведенном выше коде, есть три print
заявления и все три выполняются. Выход ls
не собирается стандартизировать непосредственно, но присваивается переменной data2
и затем печатается с помощью заключительной инструкции печати.
разница между "exec" и "system" заключается в том, что exec заменяет вашу текущую программу на "command" и никогда не возвращается в вашу программу. система, с другой стороны, вилки и запускает "command" и возвращает вам статус выхода "command", когда он будет выполнен. Задняя галочка запускает "команду", а затем возвращает строку, представляющую ее стандарт (что бы она ни напечатала на экране)
вы также можете использовать popen для запуска команд оболочки, и я думаю, что есть оболочка модуль - "использовать оболочку", которая дает вам прозрачный доступ к типичным командам оболочки.
надеюсь, что это проясняет его для вас.