루비 시스템 명령 확인 종료 코드


106

다음과 같은 루비에서 많은 시스템 호출이 있으며 해당 명령이 실패하면 스크립트가 종료되도록 종료 코드를 동시에 확인하고 싶습니다.

system("VBoxManage createvm --name test1")
system("ruby test.rb")

나는 같은 것을 원한다

system("VBoxManage createvm --name test1", 0) <-여기서 두 번째 매개 변수는 종료 코드를 확인하고 시스템 호출이 성공했는지 확인합니다. 그렇지 않으면 오류가 발생하거나 그런 종류의 작업을 수행합니다.

그게 가능할까요?

나는 이것의 라인을 따라 무언가를 시도했지만 그것도 작동하지 않았습니다.

system("ruby test.rb")
system("echo $?")

또는

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end


위의 예에서, exit_code중 - 문자열이 될 것이다 "0\n"또는 "1\n"때문에, exit_code != 0항상 true가됩니다
dgmstuart

답변:


166

로부터 문서 :

true0이 아닌 종료 상태에 false대해 명령이 0 종료 상태를 제공하면 시스템이 리턴 합니다 . nil명령 실행이 실패하면 반환 합니다.

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false

더욱이

에서 오류 상태를 확인할 수 있습니다 $?.

system("VBoxManage createvm --invalid-option")

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2

2
출력 (종료 코드 아님)을 변수로 캡처하는 방법은 무엇입니까?
アレックス

Rails 콘솔에서 이것을 테스트하고 있다면 $의 가치를 잃을 수 있다는 것을 명심하십시오. 당신은 당신의 REPL 명령의 일부로 캡처해야 [10] pry(main)> system("touch /root/test 2> /dev/null") => false [11] pry(main)> $?.exitstatus => 0 [12] pry(main)> system("touch /root/test 2> /dev/null"); $?.exitstatus => 1
lardcanoe

또 다른 우수한 비교 system역 따옴표는,, %x, 및 exec여기서 제공 : stackoverflow.com/questions/6338908/...을
톰 해리슨

38

저에게는``를 사용하여 쉘 명령을 호출하고 $? 프로세스 상태를 가져옵니다. $? 프로세스 상태 객체이며, 상태 코드, 실행 상태, pid 등을 포함하여이 객체에서 명령의 프로세스 정보를 가져올 수 있습니다.

$의 몇 가지 유용한 방법? 목적:

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid

1
Rubocop의 도움으로, 나는에 대한 읽을 별명이 있음을 발견 $?하다$CHILD_STATUS
RajaRaviVarma

26

systemfalse명령에 0이 아닌 종료 코드가 있거나 nil명령이없는 경우를 반환 합니다 .

따라서

system( "foo" ) or exit

또는

system( "foo" ) or raise "Something went wrong with foo"

작동해야하며 합리적으로 간결합니다.


6

system결과 코드가 반환되는 호출 결과를 캡처하지 않습니다 .

exit_code = system("ruby test.rb")

systembacktick-method를 포함하는 각 호출 또는 동등한 기능이 새 셸을 생성하므로 이전 셸 환경의 결과를 캡처 할 수 없습니다. 이 경우 exit_code에는 true모든 것이 잘 풀 렸고 nil그렇지 않은 경우입니다.

popen3명령은 더 낮은 수준의 세부 정보를 제공합니다.


2
Open3.capture3이러한 종류의 작업에 특히 사용하기 쉬운 방법입니다.
Tin Man

6

이를 수행하는 한 가지 방법은 and또는 사용하여 연결하는 것입니다 &&.

system("VBoxManage createvm --name test1") and system("ruby test.rb")

첫 번째 호출이 실패하면 두 번째 호출이 실행되지 않습니다.

if ()흐름 제어를 제공하기 위해로 래핑 할 수 있습니다 .

if (
  system("VBoxManage createvm --name test1") && 
  system("ruby test.rb")
) 
  # do something
else
  # do something with $?
end

이것이 내가 달성하고자하는 것입니다. 간단하고 명확합니다. 감사합니다
mochadwi 2010 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.