Ruby에서 쉘 명령을 호출하는 방법

ruby shell interop


Ruby 프로그램 내부에서 쉘 명령을 어떻게 호출합니까? 그런 다음이 명령의 출력을 Ruby로 다시 가져 오려면 어떻게합니까?




Answer 1 Steve Willard


이 설명은 내 친구의 주석이 달린 루비 스크립트 를 기반으로합니다 . 스크립트를 개선하려면 링크에서 자유롭게 업데이트하십시오.

첫째, 루비 쉘에게 호출 할 때, 그것은 일반적으로 호출 참고 /bin/sh , 하지 배쉬. 모든 시스템에서 /bin/sh 가 일부 Bash 구문을 지원하지는 않습니다 .

쉘 스크립트를 실행하는 방법은 다음과 같습니다.

cmd = "echo 'hi'" # Sample string that can be used
  1. Kernel#` 일반적으로 백틱이라고하는 커널 # `cmd`

    이것은 Bash, PHP 및 Perl을 포함한 다른 많은 언어와 같습니다.

    쉘 명령의 결과 (표준 출력)를 반환합니다.

    문서 : http://ruby-doc.org/core/Kernel.html#method-i-60

    value = `echo 'hi'`
    value = `#{cmd}`
  2. 내장 구문, %x( cmd )

    x 문자 다음에는 분리 문자가 있으며, 이는 임의의 문자 일 수 있습니다. 분리 문자가 문자 중 하나 ( , [ , { 또는 < )인 경우, 리터럴은 중첩 된 분리 문자 쌍을 고려하여 일치하는 닫는 분리 문자까지의 문자로 구성됩니다. 다른 모든 분리 문자의 경우, 리터럴은 다음에 분리 문자가 나타날 경우 문자열 보간 #{ ... } 이 허용됩니다.

    백틱과 마찬가지로 쉘 명령의 결과 (예 : 표준 출력)를 반환합니다.

    문서 : https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-Percent+Strings

    value = %x( echo 'hi' )
    value = %x[ #{cmd} ]
  3. Kernel#system

    주어진 명령을 서브 쉘에서 실행합니다.

    명령이 발견되어 성공적으로 실행되면 false 그렇지 않으면 false를 리턴 true .

    문서 : http://ruby-doc.org/core/Kernel.html#method-i-system

    wasGood = system( "echo 'hi'" )
    wasGood = system( cmd )
  4. Kernel#exec

    주어진 외부 명령을 실행하여 현재 프로세스를 대체합니다.

    아무것도 반환하지 않으면 현재 프로세스가 교체되고 계속 진행되지 않습니다.

    문서 : http://ruby-doc.org/core/Kernel.html#method-i-exec

    exec( "echo 'hi'" )
    exec( cmd ) # Note: this will never be reached because of the line above

추가 조언이 있습니다 : $? 백틱, system() 또는 %x{} 를 사용하는 경우 $CHILD_STATUS 와 동일한 , 마지막 시스템 실행 명령의 상태에 액세스합니다 . 그런 다음 exitstatuspid 속성에 액세스 할 수 있습니다 .

$?.exitstatus

자세한 내용은 다음을 참조하십시오.




Answer 2 Ian


다음은 " Ruby에서 하위 프로세스를 시작하는 각 방법을 사용하는시기 "를 기반으로 한 순서도 입니다. 또한 " 응용 프로그램이 stdout이 파이프가 아닌 터미널이라고 생각하도록 속임수 "를 참조하십시오 .

enter image description here




Answer 3 cynicalman


내가 좋아하는 방법은 %x 리터럴을 사용하는 것인데, 명령에서 따옴표를 사용하는 것이 쉽고 읽기 쉽습니다!

directorylist = %x[find . -name '*test.rb' | sort]

이 경우 현재 디렉토리 아래의 모든 테스트 파일로 파일 목록을 채우고 예상대로 처리 할 수 ​​있습니다.

directorylist.each do |filename|
  filename.chomp!
  # work with file
end



Answer 4 Mihai A


루비에서 쉘 스크립트를 실행하는 것에 대한 제 의견으로는 " 루비에서 쉘 명령을 실행하는 6 가지 방법 "이 있습니다.

출력 만 가져 오려면 백틱을 사용하십시오.

STDOUT 및 STDERR과 같은 고급 기능이 필요했기 때문에 Open4 gem을 사용했습니다. 거기에 설명 된 모든 방법이 있습니다.




Answer 5 anshul


내가 가장 좋아하는 것은 Open3

  require "open3"

  Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }