2011-06-14 1 views
312

다음 Ruby 메소드의 차이점은 무엇입니까?Ruby, exec, system 및 % x() 또는 Backticks의 차이점

exec, system%x() 또는 역 따옴표는

나는 그들이 터미널 루비를 통해 프로그래밍 명령을 실행하는 데 사용되는 알고 있지만, 나는이 작업을 수행하는 세 가지 방법이 있습니다 이유를 알고 싶습니다.

+5

이 주제에 관심이 Rubyists위한 훌륭한 책이다 : http://workingwithunixprocesses.com/ –

+0

좋은 루비가있다 해당 주제에 대한 Quicktips 기사 : [쉘 명령 실행] (http://rubyquicktips.com/post/5862861056/execute-shell-commands). –

+1

이 명령들과 많은 다른 것들은 문서에서 아주 잘 설명되어 있습니다 : [exec] (http://www.ruby-doc.org/core/Kernel.html#method-exec) [system] (http : //www.ruby-doc.org/core/Kernel.html#method-i-system) [backticks] (http://www.ruby-doc.org/core/Kernel.html#method-i-60) – zetetic

답변

339

시스템

system 방법은 시스템 프로그램을 호출합니다. 이 메소드에 문자열 인수로 명령을 제공해야합니다. 예를 들어 :

>> system("date") 
Wed Sep 4 22:03:44 CEST 2013 
=> true 

호출 된 프로그램은 루비 프로그램의 현재 STDIN, STDOUTSTDERR 객체를 사용합니다. 실제 반환 값은 true, false 또는 nil입니다. 이 예제에서 날짜는 STDIN의 IO 개체를 통해 인쇄되었습니다. 프로세스가 0 상태에서 종료되면 true을 반환하고 프로세스가 0이 아닌 상태에서 종료하면 false, 실행이 실패하면 nil을 반환합니다.

또 다른 부작용은 $?이라는 전역 변수가 Process::Status 개체로 설정되어 있다는 것입니다. 이 객체는 호출 된 프로세스의 프로세스 식별자 (PID)와 종료 상태를 포함하여 호출 자체에 대한 정보를 포함합니다.

>> system("date") 
Wed Sep 4 22:11:02 CEST 2013 
=> true 
>> $? 
=> #<Process::Status: pid 15470 exit 0> 

역 따옴표

Backticks ('') 시스템 프로그램을 호출하고, 그 출력을 리턴한다. 첫 번째 접근 방식과는 달리 명령은 문자열을 통해 제공되는 것이 아니라 백틱 쌍에 넣는 방식으로 제공됩니다.

>> `date` 
=> Wed Sep 4 22:22:51 CEST 2013 

글로벌 변수 $?도 백틱을 통해 설정됩니다. 역 따옴표를 사용하면 문자열 보간을 사용할 수도 있습니다. %x 사용

%의 (X)는()

역 따옴표 스타일에 대한 대안이다. 출력도 반환됩니다. 친척 인 %w%q과 마찬가지로 (특히) 대괄호 스타일 구분 기호가 일치하는 한 모든 구분 기호로 충분합니다. 즉, %x(date), %x{date}%x-date-은 모두 동의어입니다. 백틱처럼 %x은 문자열 보간법을 사용할 수 있습니다.

Kernel#exec 현재 프로세스 (루비 스크립트)를 사용하여 간부

exec를 통해 호출 과정으로 대체됩니다. 메서드는 문자열을 인수로 취할 수 있습니다. 이 경우 문자열은 셸 확장의 대상이됩니다. 둘 이상의 인수를 사용하는 경우 첫 번째 인수는 프로그램을 실행하는 데 사용되며 다음은 호출 할 프로그램의 인수로 제공됩니다. Open3.popen3

때때로 필요한 정보는 표준 입력이나 표준 오류에 기록되고 당신은뿐만 아니라 그 통제를 얻을 필요가있다. 여기 Open3.popen3이 편리 :

require 'open3' 

Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread| 
    pid = thread.pid 
    puts stdout.read.chomp 
end 
+1

그리고'STDIN','STDOUT','STDERR'을 어떻게 처리하는지보다 세밀하게 제어하려면'Open3.popen3'을 대신 사용하십시오; 예 : http://stackoverflow.com/a/10922097/258662 – cboettig

+1

@ platzhirsch - 아주 잘 설명되어 있습니다. 고맙습니다. – itsh

+0

감사합니다. @cboettig –

91

그들은 다른 일을합니다. exec은 현재 프로세스를 새 프로세스로 바꾸고 을 반환하지 않습니다. system은 다른 프로세스를 호출하고 은 현재 프로세스에 종료 값을 리턴합니다. 백틱을 사용하면 다른 프로세스가 호출되고 은 해당 프로세스의 출력을 현재 프로세스로 리턴합니다.

176

여기 this answer 기반으로하는 순서도이다. 참조 : using script to emulate a terminal. "유닉스 프로세스 작업"사람이 바로이 오래된 스레드를 발굴 이후

enter image description here

+1

이것은 그렇게 간단하지 않습니다. 내 경우에는 "프로세스가 완료 될 때까지 차단하는 것이 좋았으며 (필요)"하고 popen3을 사용하여 STDOUT/STDERR 출력을 확인했습니다. – Nakilon

+0

while 루프에서 랩핑하여 비 차단 호출을 (효과적으로) 차단할 수 있습니다. 블로킹 호출을 비 블로킹 호출로 쉽게 만들 수는 없습니다. – Ian