2013-09-10 62 views
74

我在ruby中有一堆系統調用,比如下面,我想同時檢查它們的退出代碼,這樣如果該命令失敗,我的腳本將退出。ruby​​系統命令檢查退出代碼

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 
+2

[使用%×捕捉命令行錯誤]的可能重複(http://stackoverflow.com/questions/4771930/catching-command-line-errors-using-x) –

+0

在上述例如,'exit_code'將是一個字符串 - 無論是「0 \ n」還是\「1 \ n」',所以'exit_code!= 0'將始終爲真 – dgmstuart

回答

129

documentation

系統如果命令給出零個退出狀態,false爲 非零退出狀態返回true。如果命令執行失敗,則返回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 
+1

以及如何將其輸出(不是退出代碼)捕獲到變量? –

+2

@ alexander-supertramp請參閱http://stackoverflow.com/q/690151/477037 – Stefan

+0

如果您正在使用Rails控制檯進行測試,請記住您可能會失去$的價值?所以你需要捕獲它作爲你的REPL命令的一部分 '[10] pry(main)> system(「touch/root/test 2>/dev/null」) => false [11] pry )> $ ?. exitstatus => 0 [12] pry(main)> system(「touch/root/test 2>/dev/null」); $ ?. exitstatus => 1' – lardcanoe

21

system返回false如果命令具有非零退出代碼,或nil如果沒有命令。

因此

system("foo") or exit 

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

應該工作,並儘量簡潔。

5

你沒有捕捉您的通話system,這是在返回的結果代碼的結果:

exit_code = system("ruby test.rb") 

記住每個system來電或同等學歷,其中包括反引號法,產生一個新的shell ,因此無法捕獲前一個shell的環境結果。在這種情況下,如果一切正常,則exit_codetrue,否則爲nil

popen3命令提供更多低級細節。

+2

['Open3.capture3'](http:/ /www.ruby-doc.org/stdlib-2.0.0/libdoc/open3/rdoc/Open3.html#method-c-capture3)是用於這類任務的特別簡單的方法。 –

+2

exit_code可能不是最好的名字 – drewish

3

一種方式是連鎖他們使用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 
15

對於我來說,我更喜歡使用``調用shell命令和檢查$?獲取進程狀態。 $?是一個進程狀態對象,你可以從這個對象中獲得該命令的進程信息,包括:狀態碼,執行狀態,pid等。

一些有用的方法$?對象:

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