Perl의 백틱, 시스템 및 exec의 차이점은 무엇입니까?


237

누군가 제발 도와주세요? Perl에서 차이점은 무엇입니까?

exec "command";

system("command");

print `command`;

쉘 명령을 실행하는 다른 방법이 있습니까?


8
여기 에는 exec가 있고 다른 하나에는 파이프가 있다는 점을 제외하고 stackoverflow.com/questions/797127/…의 거의 동일한 사본 .
Michael Myers

답변:


268

exec

명령을 실행하고 결코 반환하지 않습니다 . return함수 의 문장 과 같습니다 .

명령을 찾을 수 없으면 execfalse를 반환합니다. 명령이 발견되면 전혀 리턴하지 않으므로 true를 리턴하지 않습니다. 반환에 대한 아무 문제도 없다 STDOUT, STDERR또는 명령의 종료 상태. perlfunc함수이기 때문에 에 대한 설명서를 찾을 수 있습니다 .

체계

명령을 실행하고 명령이 완료된 후 Perl 스크립트가 계속됩니다.

리턴 값은 명령의 종료 상태입니다. 에 대한 설명서는에서 찾을 수 있습니다 perlfunc.

백틱

like system는 명령을 실행하고 명령이 완료된 후 perl 스크립트가 계속됩니다.

system반환 값 과 달리 STDOUT명령입니다. qx//백틱과 같습니다. 연산자 와 perlop다르기 때문에 에 대한 설명서를 찾을 수 있습니다 .systemexec


다른 방법들

위에서 빠진 것은 명령을 비동기 적으로 실행하는 방법입니다. 이는 perl 스크립트와 명령이 동시에 실행됨을 의미합니다. 이 작업을 수행하면 open됩니다. 그것은 당신이 읽을 수 STDOUT/ STDERR및 쓰기에 대한 STDIN명령의. 그래도 플랫폼에 따라 다릅니다.

이 작업을 쉽게 수행 할 수있는 몇 가지 모듈도 있습니다. 이 IPC::Open2IPC::Open3하고 IPC::Run뿐만 아니라, Win32::Process::Create당신이 창에있는 경우.


1
나는 당신이 s / perlcunc / perlfunc /를 의미한다고 생각합니다 ... 또한 perlipc 문서는 파이프를 여는 것에 대해 깊이있게 설명합니다.
ephemient

7
perlcunc, 아마 이것은 나의 새로운 닉네임이 될 것이다 ;-)
Ludwig Weinzierl

8
레코드의 경우 백틱과 qx []도 $? (OS 리턴 값).
jjohn

167

일반적으로 내가 사용에서 system, open, IPC::Open2, 또는 IPC::Open3내가 원하는 무엇에 따라 달라집니다. qx//운영자는 간단하지만, 너무 빠른 해킹의 매우 유용한 외부로 그 기능에 제약되어있다. 내가 찾을 수 open많은보다 간편한합니다.

system: 명령을 실행하고 명령이 리턴 될 때까지 기다립니다.

사용은 system당신이 명령을 실행 할 때, 출력에 대한 상관 없어, 그리고 펄 스크립트 명령이 완료 될 때까지 아무것도하고 싶지 않아요.

#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에 기록 무엇을 캡처 명령을 실행하려면, 그리고 펄 스크립트 명령이 완료 될 때까지 아무것도하고 싶지 않아요.

#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
}

또한 읽을 수 있습니다 waitpidperlipc설명서를.

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와 거의 같은 방식으로 작동하지만 인수와 세 번째 파일 핸들의 순서가 약간 다릅니다.


매우 유익하고 최신 답변입니다. 감사합니다 @ chas-owens
Jassi

IPC :: Open3은 대부분의 용도에 비해 너무 낮은 수준입니다. IPC :: Run3 및 IPC :: Run이 일반적으로 훨씬 더 적합합니다.
ikegami

17

먼저 매뉴얼을 인용하겠습니다.

perldoc exec () :

간부 인 함수는 시스템 명령을 실행하고 반환하지 않습니다 - 사용 시스템을 대신 간부 당신이 반환을 원하는 경우

펄독 시스템 () :

포크가 먼저 수행 되고 상위 프로세스가 하위 프로세스가 완료 될 때까지 대기 한다는 점을 제외하고는 exec LIST와 정확히 동일한 작업을 수행 합니다.

execsystem 과 달리 백틱은 반환 값을 제공하지 않고 수집 된 STDOUT을 제공합니다.

perldoc`String` :

보간 된 후 / bin / sh 또는 이와 동등한 시스템 명령으로 실행되는 문자열입니다 . 쉘 와일드 카드, 파이프 및 리디렉션이 적용됩니다. 명령 의 수집 된 표준 출력이 리턴됩니다 . 표준 오류는 영향을받지 않습니다.


대안 :

STDOUT, STDERR 또는 리턴 코드를 페치하려는보다 복잡한 시나리오에서는 IPC :: Open2IPC :: Open3 과 같은 잘 알려진 표준 모듈을 사용할 수 있습니다 .

예:

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

마지막으로 CPAN에서 실행 되는 IPC :: Run 도 살펴볼 가치가 있습니다.


3
이것은 무례한 반응입니다. 분노없이 도움을 주려고 노력해야합니다.
Shane C. Mason

1
나는 그가 단지 ol 'RTFM : P
v3을

실제로 무례 의미되지 않았다) 비록 F-단어, 어떤 오해를 피하기 위해 ... 제거
베네딕트 Waldvogel을

2
나는 그것을 무례하다고 해석하지 않았다. Brusque 일 수도 있지만 이것은 신중한 답변이 필요한 지능적인 질문은 아닙니다.
ephemient

11

Perl의 백틱 ( `) system,과 차이점은 무엇입니까 exec?

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

exec

exec명령을 실행하고 Perl 스크립트를 다시 시작하지 않습니다. 그것은 return문장 과 같은 스크립트 입니다.

명령을 찾을 수 없으면 execfalse를 반환합니다. 명령이 발견되면 전혀 리턴하지 않으므로 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스크립트 를 종료하면 첫 번째 print 명령문 만 실행됩니다. 또한 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명령 후에 스크립트가 재개 되면 세 개의 print 문이 모두 실행됩니다.

또한 실행 결과 system 는에 할당 data2되지만 할당 된 값은 0(종료 코드 ls)입니다.

여기에서 첫 번째 print명령문 의 출력을 얻은 다음 ls명령의 출력을 얻은 다음 print표준 출력의 마지막 두 명령문 의 출력을 얻 습니다.

백틱 ( `)

마찬가지로 system백틱으로 명령을 묶으면 해당 명령이 실행되고 명령이 완료된 후 Perl 스크립트가 다시 시작됩니다. 반대로 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다음 최종 인쇄 명령문으로 인쇄됩니다.


예제를 통한 최상의 설명. 고마워
Arslan Anwar

2

'exec'와 'system'의 차이점은 exec가 현재 프로그램을 'command'로 바꾸고 프로그램으로 돌아 가지 않는다는 것입니다. 반면에 시스템은 'command'를 포크하고 실행하며 실행이 완료되면 'command'의 종료 상태를 반환합니다. 백 틱은 'command'를 실행 한 다음 표준 출력을 나타내는 문자열을 반환합니다 (화면에 인쇄 된 내용).

popen을 사용하여 쉘 명령을 실행할 수도 있으며 일반적인 쉘 명령에 투명하게 액세스 할 수있는 쉘 모듈 인 '셸 사용'이 있다고 생각합니다.

그것이 당신을 위해 그것을 명확히 바랍니다.


아마도 use Shell;( search.cpan.org/dist/Shell/Shell.pm ) 을 의미 합니까? 그것은 널리 설치되지 않았거나 질문에 적용 할 수 없다고 생각합니다 ...
ephemient

1
그의 질문의 마지막 부분은 "쉘 명령을 실행하는 다른 방법이 있습니까?"였습니다. 쉘은 쉘 명령을 실행하는 또 다른 방법입니다.
Shane C. Mason

2
이 문서는 "이 패키지는 몇 가지 Perl 기능을 보여주는 쇼케이스로 포함되어 있습니다. 프로덕션 프로그램에는 사용해서는 안됩니다. 임의의 명령의 표준 출력을 얻기위한 간단한 인터페이스를 제공하지만 더 나을 수 있습니다. "필요한 것을 달성하는 방법."
Chas. Owens

2
다시, 그것은 '다른 방법이
.

잘못되고 지원되지 않는다는 경고없이 잘못되고 지원되지 않는 방법을 제공해서는 안됩니다.
Chas. Owens
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.