我試圖理解邏輯運算符優先級如何在 bash 中工作. 例如, 我原以爲, 以下命令不會回顯任何內容.
true || echo aaa && echo bbb
然而, 與我的期望相反, bbb被打印出來.
有人可以解釋一下, 我怎樣才能理解複合和 && 和 || bash 中的操作符?
最佳答案
在許多計算機語言中, 具有相同優先級的運算符是 left-associative. 也就是說, 在沒有分組結構的情況下, 首先執行最左邊的操作. Bash 是這個規則的 no exception.
這很重要, 因爲在 Bash,&& 和 || 具有相同的優先權.
那麼在你的例子中發生的是最左邊的操作 (||) 首先執行:
true || echo aaa
因爲真的顯然是真的,|| 操作符短路並且整個語句被認爲是真實的, 而不需要像您期望的那樣評估 echo aaa. 現在仍然要做最正確的操作:
(...) && echo bbb
由於第一個操作被評估爲 true(即具有 0 退出狀態), 因此就像您正在執行一樣
true && echo bbb
所以 && 不會短路, 這就是爲什麼你看到 bbb 迴應.
你會得到相同的行爲
false && echo aaa || echo bbb
基於評論的備註
您應該注意, 只有當兩個運算符具有相同的優先級時, 纔會遵循左關聯性規則. 當您將這些運算符與 [[…]] 或((…))等關鍵字結合使用或使用 - o 和 - a 運算符作爲測試或 [命令] 的參數時, 情況並非如此. 在這種情況下, AND(&& 或 - a)優先於 OR(|| 或 - o). 感謝 Stephane Chazelas 澄清這一點.
似乎 in C 和 C 類語言 && 優先級高於 || 這可能就是爲什麼你期望你的原始結構表現得像
true || (echo aaa && echo bbb).
但是, Bash 不是這種情況, 兩個運算符都具有相同的優先級, 這就是 Bash 使用左關聯性規則解析表達式的原因. 感謝 Kevin 對此提出的評論.
可能還會出現評估所有 3 個表達式的情況. 如果第一個命令返回非零退出狀態, 則爲 || 不會短路並繼續執行第二個命令. 如果第二個命令以零退出狀態返回, 那麼 && 也不會短路, 第三個命令將被執行. 感謝 Ignacio Vazquez-Abrams 對此提出的評論.