Может кто-нибудь мне помочь? В Perl, в чем разница между:
exec "command";
и
system("command");
и
print `command`;
Есть ли другие способы запуска команд оболочки?
Может кто-нибудь мне помочь? В Perl, в чем разница между:
exec "command";
и
system("command");
и
print `command`;
Есть ли другие способы запуска команд оболочки?
выполняет команду и никогда не возвращается. Это как оператор return
в функции.
Если команда не найдена, exec
возвращает false. Он никогда не возвращает true, потому что если команда найдена, она никогда не возвращается вообще. Также нет смысла возвращать STDOUT
, STDERR
или статус выхода команды. Вы можете найти документацию об этом в perlfunc
, потому что это функция.
выполняет команду, а ваш Perl script продолжается после завершения команды.
Возвращаемое значение - это статус выхода команды. Вы можете найти документацию об этом в perlfunc
.
как system
выполняет команду, и ваш perl script продолжается после завершения команды.
В отличие от system
возвращаемое значение STDOUT
команды. qx//
эквивалентен обратным отсчетам. Вы можете найти документацию об этом в perlop
, потому что в отличие от system
и exec
это оператор.
То, что отсутствует в приведенном выше примере, - это способ выполнения команды асинхронно.
Это означает, что ваш perl script и ваша команда запускаются одновременно.
Это можно сделать с помощью open
.
Он позволяет читать STDOUT
/STDERR
и записывать в STDIN
вашей команды.
Это зависит от платформы.
Есть также несколько модулей, которые могут облегчить выполнение этих задач.
Существует IPC::Open2
и IPC::Open3
и IPC::Run
, а также
Win32::Process::Create
, если вы находитесь в окнах.
В общем, я использую system
, open
, IPC::Open2
или IPC::Open3
в зависимости от того, что я хочу делать. Оператор qx//
, хотя и простой, слишком сдерживает свою функциональность, чтобы быть очень полезной вне быстрых хаков. Я нахожу open
гораздо удобнее.
system
: запустите команду и дождитесь ее возвратаИспользуйте system
, если вы хотите запустить команду, не заботитесь о ее выходе и не хотите, чтобы Perl script ничего не делал, пока команда не закончится.
#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 script делал что-либо до тех пор, пока команда не завершится.
#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.
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
, когда вам нужно захватить все три стандартных дескриптора файла процесса. Я бы написал пример, но он работает в основном так же, как IPC:: Open2, но с немного другим порядком для аргументов и третьего дескриптора файла.
Функция exec выполняет системную команду, а никогда не возвращает - использует систему вместо exec, если вы хотите, чтобы она вернула
Точно так же, как exec LIST, за исключением того, что fork выполняется, и родительский процесс ожидает завершения дочернего процесса.
В отличие от 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 script. Это для оператора script как a 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
, оставляющего script, выполняется только первый оператор печати. Кроме того, команда exec
не назначается какой-либо переменной.
Здесь вы получаете только результат первого оператора print
и выполнения команды ls
при стандартном выходе.
system
system
выполняет команду, а ваш Perl script возобновляется после завершения команды. Возвращаемое значение - это статус выхода команды. Вы можете найти документацию об этом в 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
. По мере возобновления script после команды system
выполняются все три оператора печати.
Кроме того, результат выполнения system
присваивается data2
, но назначенное значение 0
(код выхода из ls
).
Здесь вы получаете вывод первого оператора print
, а затем команды ls
, за которым следуют выходы последних двух операторов print
на стандартном выходе.
`
)Подобно system
, при выполнении команды в backticks выполняется эта команда, и ваш Perl script возобновляется после завершения команды. В отличие от system
, возвращаемое значение STDOUT
команды. qx//
эквивалентен обратным выводам. Вы можете найти документацию об этом в 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 заменяет вашу текущую программу "командой", а NEVER возвращается в вашу программу. система, с другой стороны, использует forks и запускает команду 'и возвращает вам статус выхода' command ', когда он выполняется. Задний тик запускает "команду", а затем возвращает строку, представляющую ее стандартную версию (независимо от того, что она напечатала на экране).
Вы также можете использовать popen для запуска команд оболочки, и я думаю, что есть оболочный модуль - "use shell", который дает вам прозрачный доступ к типичным командам оболочки.
Надеюсь, что это разъяснит вам.