2014-10-02 35 views
1

我想在我的bash腳本擊而進行數值計算

#!/bin/bash 
set -x 
# Copy merchant files 
set -o pipefail -o errexit 

a=0 
b=0 
c=$(expr $a + $b) 
if [[ $(expr $c) -lt 10 ]]; then 
    echo true 
fi 

預期這從來沒有真正打印執行以下邏輯退出。產生的輸出是:

++ set -o pipefail -o errexit 
++ a=0 
++ b=0 
+++ expr 0 + 0 
++ c=0 

而且上述邏輯不工作時A和B兩者都爲0,如果任何一個是非零它工作正常。如果我修改我的邏輯和,而不是計算C使用EXPR直接在它是否工作正常,如預期無關的價值和b打印真正

#!/bin/bash 
set -x 
# Copy merchant files 
set -o pipefail -o errexit 

a=0 
b=0 
if [[ $(expr $a + $b) -lt 10 ]]; then 
    echo true 
fi 

是否有人可以給我解釋一下什麼是錯與第一一段代碼。

+1

這不是「崩潰」,它是「退出」。 – tripleee 2014-10-02 06:43:38

+0

爲什麼你用expr來算術? 'c = $((a + b))'和'if [[$ c -lt 10]]'可以正常工作。 – chepner 2014-10-02 14:11:53

回答

5

問題是,如果算術表達式求值爲0,那麼expr將返回一個非零退出狀態(shell解釋爲錯誤)。這不是立即與set -o errexit兼容。

既然您使用的是Bash,那麼簡單的解決方法是根本不使用expr

c=$((a + b)) 
if [[ "$c" -lt 10 ]]; then 
    echo true 
fi 

如果你想留在expr出於某種原因,習慣成語是要與|| true或其變型以允許捕獲錯誤。

c=$(expr "$a" + "$b") || true 

當你重構計算入if條款,這是「某些變種」,即errexit不能在ifwhile從句(顯然的條件部分的故障觸發;否則,這將是不可能的在set -o errexit下使用條件編寫代碼)。

+0

實際上使用'c = $((a + b))'或者甚至是'((c = a + b))'在[tag:bash]中使用非內置的'expr'會更加有效。我建議不要使用'-o errexit',因爲可以面對意想不到的腳本終止。 – TrueY 2014-10-02 07:38:49

+0

是的,如果可以的話,應避免使用'expr'。我不同意對'set -o errexit'又名'set -e'的警告,但是你需要知道它什麼時候有用,以及如何正確使用它。 – tripleee 2014-10-02 08:06:17

+0

個人而言,我更喜歡對隱式錯誤進行顯式的錯誤處理。主要是因爲退出代碼不僅用於報告錯誤,而且還返回邏輯狀態(請參閱grep,diff,cmp,ps,kill,expr等)。其實'expr'對我來說是新的。 ;) – TrueY 2014-10-02 09:30:29