Bash

bash腳本中邏輯與(&&)和或(||)的悖論來檢查命令是否成功執行(退出程式碼0被解釋為真)

  • February 5, 2021

所以我很明白退出程式碼0被認為是程序執行的成功。然後我們在 bash 腳本中使用它,ANDOR根據第一個程序的退出狀態執行下一個程序。一個很好的例子可以在這裡找到: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 中,但工作方式相同。)

POSIX 定義||類似,正如Bash 的文件所說):

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列印什麼,為什麼?)

引用自:https://unix.stackexchange.com/questions/632670