Може хтось, будь ласка, допоможе мені? У Perl, яка різниця між:
exec "command";
і
system("command");
і
print `command`;
Чи є й інші способи запускати команди оболонки?
Може хтось, будь ласка, допоможе мені? У Perl, яка різниця між:
exec "command";
і
system("command");
і
print `command`;
Чи є й інші способи запускати команди оболонки?
Відповіді:
виконує команду і ніколи не повертається . Це як return
твердження у функції.
Якщо команда не знайдена, exec
повертається помилково. Він ніколи не повертає істину, тому що якщо команда знайдена, вона ніколи не повертається. Там також немає сенсу повертатися STDOUT
, STDERR
або статус завершення команди. Ви можете знайти документацію про це perlfunc
, оскільки це функція.
виконує команду, і ваш сценарій Perl продовжується після завершення команди.
Повернене значення - це стан виходу команди. Ви можете знайти документацію про це в perlfunc
.
як system
виконує команду, і ваш скрипт perl продовжується після завершення команди.
Навпаки, system
повертається значення STDOUT
команди.
qx//
еквівалентно задній план. Ви можете знайти документацію про це в perlop
, тому що в відміну від system
і exec
він є оператором.
Чого не вистачає у вищезазначеному, це спосіб асинхронного виконання команди. Це означає, що ваш скрипт perl і ваша команда працюють одночасно. Це можна досягти за допомогою open
. Це дозволяє читати STDOUT
/ STDERR
записувати на STDIN
вашу команду. Це залежить від платформи.
Також є кілька модулів, які можуть полегшити це завдання. Є IPC::Open2
і IPC::Open3
і IPC::Run
, як і
Win32::Process::Create
якщо ви на вікнах.
Загалом використанні I 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 процесу.
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 та системи , backticks не дає значення повернення, а зібране STDOUT.
Рядок, який (можливо) інтерполюється і потім виконується у вигляді системної команди з / bin / sh або його еквівалентом. Підстановочні символи, труби та перенаправлення оболонок будуть шануватися. Зібраний стандартний вихід команди повертається ; стандартна помилка не впливає.
У більш складних сценаріях, де потрібно отримати 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 :: Запуск із CPAN також варто переглянути…
Яка різниця між задумами Perl ( `
) system
, та exec
?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
exec
exec
виконує команду і ніколи не поновлює сценарій Perl. Це до сценарію, як return
заява - до функції.
Якщо команда не знайдена, exec
повертає false. Він ніколи не повертає істину, тому що якщо команда знайдена, вона ніколи не повертається взагалі. Там також немає сенсу повертатися 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
буде призначений data2
, але присвоєне значення 0
(вихід код з ls
).
Тут ви отримуєте вихід першого print
оператора, а потім ls
команди, а потім виходи з двох останніх print
висловлювань на стандартне виведення.
`
)Мовляв system
, вкладення команди в backticks виконує цю команду, і ваш скрипт Perl поновлюється після завершення команди. На відміну від system
, значення, що повертається, є STDOUT
командою. qx//
еквівалентно задній план. Ви можете знайти документацію про це в perlop , тому що на відміну від system і 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 замінює поточну програму на "команду", і НІКОЛИ не повертається до вашої програми. З іншого боку, система розкручує та виконує команду і повертає вам статус виходу "команда", коли вона виконана. Задня галочка виконує команду, а потім повертає рядок, що представляє її стандарт (усе, що було б надруковано на екрані)
Ви також можете використовувати popen для запуску команд оболонки, і я думаю, що є модуль оболонки - «використовувати оболонку», який надає прозорий доступ до типових команд оболонок.
Сподіваємось, що це вам роз’яснить.
use Shell;
( search.cpan.org/dist/Shell/Shell.pm )? Це не широко встановлено, і це не стосується питання, я думаю ...