bash腳本中邏輯與(&&)和或(||)的悖論來檢查命令是否成功執行(退出程式碼0被解釋為真)
所以我很明白退出程式碼
0
被認為是程序執行的成功。然後我們在 bash 腳本中使用它,AND
並OR
根據第一個程序的退出狀態執行下一個程序。一個很好的例子可以在這裡找到:https ://unix.stackexchange.com/a/187148/454362這是否意味著
0
被解釋為真,而除零以外的任何其他數字都被解釋為假?這與我所知道的所有程式語言相反。那麼我可以假設 bash 在內部使用邏輯NOT
將退出程式碼反轉為正確的假/真值嗎?因此,這些是一些範例:
#should result in false, and bash shows 0 as false echo $(( 1 && 0 )) # should result in true, and bash shows 1 as true echo $(( 1 || 0 )) # does not show 'hi'; even though if false is zero per first example, then # this should be considered success exit code and 'hi' to be shown!! false && echo 'hi' # does show 'hi'. It first runs the "echo 'hi'" and interprets its exit # status of zero as success, but then false stops the 2nd hi. echo 'hi' && false && echo ' 2nd hi' # shows 'hi 2nd hi' echo 'hi' && (( 1 || 0 )) && echo ' 2nd hi'
看來我正在回答我自己的問題。但如果有人知道 bash 處理的內部,我只想澄清一下。
您連結到的文章中的範例如下:
false && echo "OK" true || echo "OK"
在這種情況下,對於程序的退出狀態,是的,
0
是真的,其他的都是假的。(是的,true
並且false
是這裡的程序。可能內置在 shell 中,但工作方式相同。)AND 列表
控制運算符“&&”表示 AND 列表。格式應為:應執行 第一個命令 1。如果其退出狀態為零,則應執行command2 ,依此類推,…
*command1* [ && *command2*] ...
是的,這與幾乎所有其他上下文和程式語言中使用的約定相反。再說一次,在 C 語言中,函式在成功時返回零,在錯誤時返回非零錯誤程式碼也很常見。這樣,您可以區分不同類型的錯誤(*)。當然,如果您的函式需要返回一些有用的值(例如指針),那麼這實際上並不適用,並且就 C 語言而言,0 是虛假的。反正就是不一樣。
我認為對實施進行任何假設都不是一個好主意。請記住,在這種情況下,零為真,例如 (true && true) 為 (true)。
(* 就像家庭一樣,快樂的系統呼叫都是相似的。不快樂的系統呼叫各不相同。)
然後你的例子:
#should result in false, and bash shows 0 as false echo $(( 1 && 0 ))
在這裡,您
&&
在算術上下文中使用,它不遵守與退出狀態相同的規則。這裡,0 為假,1 為真。(true AND false) 也是如此1 && 0
,即 (false) 或 0。# should result in true, and bash shows 1 as true echo $(( 1 || 0 ))
與上述類似。
# does not show 'hi'; even though if false is zero per first example, then # this should be considered success exit code and 'hi' to be shown!! false && echo 'hi'
呼叫的實用程序
false
以狀態 1(或至少一些非零值)退出。&&
在這種情況下,這是虛假的,因此通過短路邏輯跳過右側。# does show 'hi'. It first runs the "echo 'hi'" and interprets its exit # status of zero as success, but then false stops the 2nd hi. echo 'hi' && false && echo ' 2nd hi'
一樣。
# shows 'hi 2nd hi' echo 'hi' && (( 1 || 0 )) && echo ' 2nd hi'
您
1 || 0
在這裡使用過,無論哪種方式都是正確的,並且數值在算術上下文中有些消失了。讓我們試試這些:$ echo foo && (( 0 )) && echo bar foo $ echo foo && (( 1 )) && echo bar foo bar
現在,
((...))
是一個算術構造(如$((...))
),在其中,0 是假的。不像$((...))
,((...))
也是一個命令,所以有一個退出狀態。如果內部表達式的計算結果為非零(真實),則它以零(真實)退出;如果內部表達式的計算結果為零(假),則為 1(假)。好的,這可能會令人困惑,但最終結果是類似 C 的對零的隱式比較在其中工作,並且當將它與 shell 的條件句一起使用時,您會從中得到相同的真值。因此,
while (( i-- )); do ...
循環直到i
變為零。(
(( foo ))
不是標準的,但受 ksh/Zsh/Bash 支持。它的標準解釋是foo
兩個嵌套子 shell 中的命令,因此可能會給出“找不到命令 ‘foo’”錯誤。)可能還值得指出的是,類似的東西
(( true )) && echo maybe
可能不會列印任何東西。在算術上下文中,純單詞被視為變數的名稱(在許多 shell 中遞歸),因此除非您將變數true
設置為非零值,(( true ))
否則將為 false。(來自混淆部門的想法是執行
true=0; false=1; true() (exit 1); false() (exit 0);
。現在true && (( false )) || echo maybe && echo maybe not
列印什麼,為什麼?)