2016-03-01 31 views
0

首先我不是Bash專業版。我幾個月前發現,如果我使用帶花括號的短路操作符&&||,那麼如果第一條語句以真值存在,如果真塊中的最後一條語句退出非零,那麼失敗塊也將被執行。就像這樣:瞭解Bash短路

returnNumber 0 && { 
    echo 'OK' 
    returnNumber 1 
} || { 
    echo 'NG' 
} 

將輸出:

OK 
NG 

於是,我找了這個最簡單的解決方案,以及與此想出了:

returnNumber 0 && { 
    echo 'OK' 
    returnNumber 1 
    : 
} || { 
    echo 'NG' 
} 

我知道,這是很容易忽略內置結腸,但它是一種解決方法的正確方法?

+0

不要運動了使用特殊的語法。當你只寫'if-then-else-fi'時,大多數人都會理解。 嘗試考慮有效的例外情況。我仍然不確定我的答案http://stackoverflow.com/a/28478184/3220113:它是有效的,但很難閱讀。 –

回答

5

這實際上是一個很常見的Bash pitfall。它是不是的一個bug。

returnNumber 0的計算結果爲真,所以第二個塊(由邏輯和&&加入)也進行評估以確保first && second的結果仍然爲真。
第二個塊輸出OK但計算結果爲false,所以現在first && second的結果爲false。這意味着第三部分(由邏輯或||加入)也必須進行評估,導致也會顯示NG


而不是依靠&&||,你應該使用if聲明:

if returnNumber 0; then 
    echo 'OK' 
    returnNumber 1 
else 
    echo 'NG' 
fi 

TL;博士:切勿使用x && y || zy可以返回一個非零退出狀態。

0

Llama先生已經正確地回答了這個問題,這只是爲了快速參考不同的「組合」會發生什麼。 cmd0是具有零退出狀態的「命令」,且cmd1的值不爲零。

cmd0() { echo -n "[[email protected]]"; return 0; } 
cmd1() { echo -n "[[email protected]]"; return 1; } 
second() { echo "[second]"; } 

doit() { echo "case: [email protected]"; eval "[email protected]"; echo; } 

doit 'cmd0 start && cmd0 first && second' 
doit 'cmd0 start && cmd0 first || second' 
doit 'cmd0 start || cmd0 first && second' 
doit 'cmd0 start || cmd0 first || second' 

doit 'cmd0 start && cmd1 first && second' 
doit 'cmd0 start && cmd1 first || second' 
doit 'cmd0 start || cmd1 first && second' 
doit 'cmd0 start || cmd1 first || second' 

doit 'cmd1 start && cmd0 first && second' 
doit 'cmd1 start && cmd0 first || second' 
doit 'cmd1 start || cmd0 first && second' 
doit 'cmd1 start || cmd0 first || second' 

doit 'cmd1 start && cmd1 first && second' 
doit 'cmd1 start && cmd1 first || second' 
doit 'cmd1 start || cmd1 first && second' 
doit 'cmd1 start || cmd1 first || second' 

生產:

case: cmd0 start && cmd0 first && second 
[start-0][first-0][second] 

case: cmd0 start && cmd0 first || second 
[start-0][first-0] 

case: cmd0 start || cmd0 first && second 
[start-0][second] 

case: cmd0 start || cmd0 first || second 
[start-0] 

case: cmd0 start && cmd1 first && second 
[start-0][first-1] 

case: cmd0 start && cmd1 first || second 
[start-0][first-1][second] 

case: cmd0 start || cmd1 first && second 
[start-0][second] 

case: cmd0 start || cmd1 first || second 
[start-0] 

case: cmd1 start && cmd0 first && second 
[start-1] 

case: cmd1 start && cmd0 first || second 
[start-1][second] 

case: cmd1 start || cmd0 first && second 
[start-1][first-0][second] 

case: cmd1 start || cmd0 first || second 
[start-1][first-0] 

case: cmd1 start && cmd1 first && second 
[start-1] 

case: cmd1 start && cmd1 first || second 
[start-1][second] 

case: cmd1 start || cmd1 first && second 
[start-1][first-1] 

case: cmd1 start || cmd1 first || second 
[start-1][first-1][second]