루비, exec, 시스템과 % x () 또는 백틱의 차이점


370

다음 Ruby 메소드의 차이점은 무엇입니까?

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

Ruby를 통해 프로그래밍 방식으로 터미널 명령을 실행하는 데 사용되지만 3 가지 방법이있는 이유를 알고 싶습니다.


1
이 명령들과 다른 많은 것들이 문서에서 잘 설명되어 있습니다 : exec 시스템 백틱
zetetic

1
해당 주제에 대한 훌륭한 Ruby Quicktips 기사가 있습니다 : 셸 명령 실행 .
Simon Perepelitsa 2016 년

6
누군가가이 오래된 실을 파헤 쳤기 때문에 "Unix 프로세스로 작업하기"는 주제에 관심이있는 루비 스트를위한 훌륭한 책입니다 : workingwithunixprocesses.com
Michael Kohl

1
나는 답이 언급되지 않은 것에 놀랐다 sh.
Dennis

@Dennis이 질문을 제기 할 때 루비 1.9.3 *이 릴리스되지 않았습니다.
Mr. Black

답변:


411

체계

system메소드는 시스템 프로그램을 호출합니다. 이 메소드에 명령을 문자열 인수로 제공해야합니다. 예를 들면 다음과 같습니다.

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

호출 된 프로그램은 전류를 사용 STDIN, STDOUT그리고 STDERR루비 프로그램의 객체. 사실, 실제 반환 값 중 하나입니다 true, false또는 nil. 이 예에서 날짜는의 IO 객체를 통해 인쇄되었습니다 STDIN. true프로세스가 0 상태로 종료 된 경우, 프로세스가 0이 아닌 상태로 false종료 된 nil경우 및 실행이 실패한 경우 메소드가 리턴 합니다 .

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

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

백틱

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

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

전역 변수 $?도 백틱을 통해 설정됩니다. 백틱을 사용하면 문자열 보간을 사용할 수도 있습니다.

%엑스()

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

exec

Kernel#exec현재 프로세스 (Ruby 스크립트) 를 사용 하여를 통해 호출 된 프로세스로 바뀝니다 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

3
그리고 호출 핸들을 얼마나 더 세분화 된 제어를위한 STDIN, STDOUT, STDERR, 고려 Open3.popen3대신; 예 : stackoverflow.com/a/10922097/258662
cboettig at 12:14

1
백틱이 내 문제를 해결 한 문자열 보간을 지원한다고 언급 해 주셔서 감사합니다.
adg

244

이 답변을 기반으로 한 흐름도입니다 . 터미널 에뮬레이션에 사용script 하기도 참조하십시오 .

여기에 이미지 설명을 입력하십시오


3
이것은 그렇게 간단하지 않습니다. 제 경우에는 popen3을 사용하여 STDOUT / STDERR 출력을 확인하려면 "프로세스가 완료 될 때까지 차단해야합니다 (필요)"였습니다.
Nakilon

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

106

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.