В чем разница между 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, но с немного другим порядком аргументов и третьим дескриптором файла.


позвольте мне сначала процитировать руководства:

perldoc exec ():

функция exec выполняет системную команду и никогда не возвращает-- use система вместо exec если вы хотите вернуть

perldoc system ():

делает то же самое , что и exec LIST, за исключением того, что вилка делается во-первых, и родительский процесс ждет, пока дочерний процесс, чтобы закончить.

В отличие от exec и система, backticks не дают вам возвращаемое значение, но собранный STDOUT.

perldoc 'String':

строка, которая (возможно) интерполируется, а затем выполняется как системная команда с / 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 для запуска команд оболочки, и я думаю, что есть оболочка модуль - "использовать оболочку", которая дает вам прозрачный доступ к типичным командам оболочки.

надеюсь, что это проясняет его для вас.