Jaka jest różnica między backsticami Perla, systemem i exec?

Czy ktoś może mi pomóc? W Perlu, jaka jest różnica między:

exec "command";

I

system("command");

I

print `command`;

Czy są też inne sposoby uruchamiania poleceń powłoki?

 241
Author: brian d foy, 2009-04-28

5 answers

Exec

Wykonuje polecenie i nigdy nie zwraca . To jak return wyrażenie w funkcji.

Jeśli polecenie nie zostanie znalezione exec zwraca false. Nigdy nie zwraca true, ponieważ jeśli polecenie zostanie znalezione, nigdy nie powraca. Nie ma też sensu wracać STDOUT, STDERR lub kończy działanie polecenia. Dokumentację na ten temat można znaleźć w perlfunc, ponieważ jest to funkcja.

System

Wykonuje polecenie i twój skrypt Perla jest kontynuowany po zakończeniu polecenia.

Wartością zwracaną jest status zakończenia polecenia. Dokumentację na ten temat można znaleźć w perlfunc.

Backticks

Podobnie jak system wykonuje polecenie i twój skrypt Perla jest kontynuowany po zakończeniu polecenia.

W przeciwieństwie do system zwracana wartość to STDOUT z dowództwo. qx// jest odpowiednikiem backticks. Dokumentację na ten temat można znaleźć w perlop, ponieważ w przeciwieństwie do system i exec jest operatorem.


Inne sposoby

W powyższym przykładzie brakuje sposobu wykonania polecenia asynchronicznie. Oznacza to, że skrypt Perla i polecenie działają jednocześnie. Można to osiągnąć za pomocą open. Pozwala na odczyt STDOUT/STDERR i napisz do STDIN swojego dowództwo. Jest to jednak zależne od platformy.

Istnieje również kilka modułów, które mogą ułatwić to zadanie. Jest IPC::Open2 i IPC::Open3 i IPC::Run, a także Win32::Process::Create jeśli jesteś na windows.

 273
Author: Ludwig Weinzierl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-23 01:24:43

Ogólnie używam system, open, IPC::Open2, lub IPC::Open3 w zależności od tego, co chcę zrobić. Operator qx//, choć prosty, jest zbyt ograniczony w swojej funkcjonalności, aby był bardzo przydatny poza szybkimi hackami. Uważam, że [7]} jest o wiele bardziej poręczny.

system: uruchom polecenie i poczekaj, aż zwróci

Użyj system Gdy chcesz uruchomić polecenie, nie dbaj o jego wynik i nie chcesz, aby skrypt Perla robił cokolwiek, dopóki nie wykonasz polecenia wykończenia.

#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");

Lub

#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// w tym celu należy uruchomić polecenie i przechwycić jego STDOUT.]}

Użyj qx// gdy chcesz uruchomić polecenie, przechwyć to, co zapisuje na STDOUT i nie chcesz, aby skrypt Perla robił cokolwiek, dopóki polecenie nie zakończy się.

#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: zastąp bieżący proces innym procesem.

Użyj exec wraz z fork gdy chcesz uruchomić polecenie, nie dbaj o jego wynik i nie chcę poczekać, aż wróci. system jest naprawdę po prostu

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
}

Możesz również przeczytać waitpid oraz perlipc podręczniki.

open: w tym celu należy uruchomić proces i utworzyć rurę na jego STDIN lub STDERR

Użyj open, Gdy chcesz zapisać dane na STDIN procesu lub odczytać dane ze STDOUT procesu (ale nie oba w tym samym czasie).

#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 : uruchom proces i utwórz rurę zarówno na STDIN, jak i STDOUT

Użyj IPC::Open2, gdy musisz odczytywać i zapisywać na STDIN i STDOUT procesu.

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>;

W tym celu należy uruchomić proces i utworzyć rurę na STDIN, STDOUT i STDERR.]}

Użyj IPC::Open3, gdy musisz przechwycić wszystkie trzy standardowe uchwyty plików procesu. Napisałbym przykład, ale działa to w większości tak samo jak IPC:: Open2, ale z nieco inną kolejnością argumentów i trzecim uchwytem pliku.

 172
Author: Chas. Owens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-21 15:36:51

Pozwolę sobie najpierw zacytować podręczniki:

Perldoc exec():

Funkcja exec wykonuje polecenie systemowe i nigdy nie zwraca-- użyj system zamiast exec jeśli chcesz zwrócić

System Perldoc():

Robi dokładnie to samo co exec LIST, z tym wyjątkiem, że fork jest wykonywany pierwszy, a proces rodzic czeka na zakończenie procesu potomnego.

W przeciwieństwie do exec i system , backticki nie podają wartości zwracanej, ale pobranego STDOUT.

Perldoc " String`:

Łańcuch znaków, który jest (prawdopodobnie) interpolowany, a następnie wykonywany jako polecenie systemowe z /bin/sh lub jego odpowiednikiem. Symbole wieloznaczne powłoki, rury i przekierowania będą honorowane. Pobrane standardowe wyjście polecenia jest zwracane ; standardowy błąd to / align = "left" /


Alternatywy:

W bardziej złożonych scenariuszach, gdzie chcesz pobrać STDOUT, STDERR lub kod powrotu, możesz użyć znanych standardowych modułów, takich jak IPC:: Open2 i IPC:: Open3 .

Przykład:

use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

Wreszcie, IPC:: Run z CPAN też warto zajrzeć ...

 17
Author: Benedikt Waldvogel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 22:35:13

Jaka jest różnica między backsticami Perla (`), system, i exec?

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;

exec

exec wykonuje polecenie i nigdy nie wznawia skryptu Perla. To do skryptu jak return instrukcja jest do funkcji.

Jeśli polecenie nie zostanie znalezione, exec zwraca false. Nigdy nie zwraca true, ponieważ jeśli polecenie zostanie znalezione, nigdy nie wróci w ogóle. Nie ma też sensu wracać STDOUT, STDERR lub kończy działanie polecenia. Można znaleźć dokumentację o jest w perlfunc , ponieważ jest funkcją.

Np.:

#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";

W powyższym kodzie znajdują się trzy polecenia print, ale z powodu opuszczenia skryptu, wykonywana jest tylko pierwsza instrukcja print. Ponadto wyjście polecenia exec nie jest przypisywane do żadnej zmiennej.

Tutaj, tylko otrzymujesz tylko wyjście pierwszej print instrukcji i wykonania ls polecenia na standardowym wyjściu.

system

system wykonuje polecenie i twoje Skrypt Perla jest wznawiany po zakończeniu polecenia. Zwracaną wartością jest status zakończenia polecenia. Dokumentację można znaleźć w perlfunc.

Np.:

#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";

W powyższym kodzie znajdują się trzy print stwierdzenia. Gdy skrypt jest wznawiany po poleceniu system, wykonywane są wszystkie trzy polecenia print.

Również wynik biegu system jest przypisane do data2, ale przypisaną wartością jest 0 (kod wyjścia z ls).

Tutaj otrzymujesz wyjście pierwszej instrukcji print, następnie polecenia ls, a następnie wyjścia dwóch ostatnich instrukcji print na standardowym wyjściu.

Backticks (`)

Podobnie jak system, załączenie polecenia w backticks wykonuje to polecenie, a skrypt Perla jest wznawiany po jego zakończeniu. W przeciwieństwie do system, wartością zwracaną jest STDOUT polecenia. qx// jest odpowiednikiem backticks. Możesz znaleźć dokumentację o tym w perlop, ponieważ w przeciwieństwie do systemu i exec jest operatorem.

Np.:

#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";

W powyższym kodzie są trzy print instrukcje i wszystkie trzy są wykonywane. Wyjście ls nie będzie bezpośrednio standardowe, ale zostanie przypisane do zmiennej data2, a następnie wydrukowane przez ostateczną instrukcję print.

 12
Author: linuxtestside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-04 12:19:04

Różnica między 'exec' a 'system' polega na tym, że exec zastępuje twój bieżący program 'command' i nigdy nie wraca do twojego programu. system, z drugiej strony, rozwidla i uruchamia 'command' i zwraca ci status zakończenia 'command' po zakończeniu działania. Back tick uruchamia 'command', a następnie zwraca łańcuch reprezentujący jego standardowe wyjście (niezależnie od tego, co wydrukuje na ekranie)

Możesz również użyć popen do uruchamiania poleceń powłoki i myślę, że istnieje moduł powłoki - 'użyj powłoki', która daje przejrzysty dostęp do typowych poleceń powłoki.

Mam nadzieję, że to ci wyjaśni.

 2
Author: Shane C. Mason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 22:01:48