2017-08-15 141 views
0

我使用Ruby來調用通過shell腳本:使用Ruby來調用一個shell腳本退出代碼總是返回0

%x[ /root/script.sh -k -m -l -w -p] 
exitCode = %x[echo $?] 

if exitCode != 0 
    do something 
else 
    do something else 
end 

我的問題是退出代碼始終爲0,甚至當我逼腳本失敗。我如何正確獲取腳本的退出代碼?

編輯: 好的來到今天早上開始通過腳本挖,因爲我無法得到任何東西的錯誤代碼0以外的腳本看起來像這樣...

failed() { 
     if [ "$1" -ne 0 ] ; then 
      echo "$2 failed. INSTALLATION FAILED! Exiting."; 
     exit 1; 
    fi 
} 

{ 

function 1 
function 2.. 
function ..20 

} | tee -a logFile.log 

所以最後腳本運行的東西總是這個日誌文件,這意味着我永遠不會得到真正的退出代碼。

+0

相關:[從Ruby調用shell命令](https://stackoverflow.com/questions/2232/calling-shell-commands-from-ruby)。你可以這樣做'exitCode = $ ?. exitstatus' –

+0

我剛剛試過,我得到一個TypeError 沒有將Integer隱式轉換爲String。 所以我試着做exitCode = $ ?. exitstatus.to_i 我仍然得到相同的錯誤,雖然 – InsertNameHere

+0

有趣。 'ruby -e'%x [/root/script.sh -k -m -l -w -p];退出碼= $?退出狀態;打印exitCode''也失敗了? –

回答

1

回聲正確;檢查你的最後一個過程而不是

什麼是錯的,因爲/bin/echo或shell內置echo返回成功,除非標準輸出被關閉或某些其他錯誤發生

您當前的代碼幾乎總是將評估其if語句爲真。考慮以下猛砸片段:

echo `false`; echo $? # 0 
echo >&-; echo $?  # 1 

此外,在當前的代碼,退出碼是一個字符串,而不是一個整數。它被分配了回顯命令的標準輸出,因此在嘗試進行有效比較之前,必須先調用Kernel#IntegerString#to_i來投射變量。例如,請考慮以下的Ruby:

`echo $?`.class #=> String 
"0" == 0  #=> false 
"0".to_i == 0 #=> true 

如何解決一般情況

您需要直接測試exit status,或檢查捕獲的輸出。例如,在Ruby中,你可以測試/斌/假命令與上次狀態:

captured_output = `/bin/false` 
$?.exitstatus 
#=> 1 

修復您的具體實例

如果你不明白上面的任何東西,只是解決您的通過剝離所有非必需品的代碼。根據你的例子,你不需要臨時變量,也不需要存儲標準輸出。除非您正在評估特定的非零退出狀態,否則您甚至不需要直接檢查進程狀態,甚至不需要使用相等語句。

按照KISS原則,只是評估Kernel#system調用的真實性。例如:

# Just call system if you don't care about the output. 
# The result will be true, false, or nil. 
if system('/root/script.sh -k -m -l -w -p') 
    'clean exit' 
else 
    "non-zero exit: #{$?}" 
end 
+0

我仍然無法得到這個工作 %×[/root/script.sh -k -m -l -p -w] captured_output = '假' \t \t \t把$?退出狀態 它仍然隨時回來爲0 – InsertNameHere

+1

你應該**不要**使用'%x'。查看CodeGnome提供的代碼。我建議的代碼的唯一變體是執行'system('/ root/script.sh -k -m -l -w -p> dev/null')',因爲你對正在執行的腳本的實際標準輸出不感興趣。 – user1934428

相關問題