Shell-Script

zsh算術比較給出誤報

  • April 21, 2021

為什麼將 0 作為參數傳遞會導致誤報(列印“True”)?

#!/bin/zsh

k="$1"

if ((0 < k < 1))
then
   echo "True"
fi

注意這個腳本叫做stitch_applier.sh

終端

% ./stitch_applier.sh 0
True

這是在 Linux 系統上執行的。

shell 的算法不支持這樣的鍊式比較。相反,第一個a < b返回1or 0,具體取決於關係是否為真。

因此,如果k0,那麼((0 < k < 1))((0 < 0 < 1)),與(( (0 < 0) < 1))左關聯相同。零不小於零,所以0 < 0是假的,所以在算術上下文中,0。然後我們有0 < 1,這是真的,你去。

如果要測試是否k在範圍內,則需要執行((0 < k && k < 1)).

請注意,例如 Bash 和許多其他 shell 只處理整數算術,並且沒有嚴格介於 0 和 1 之間的整數,因此在這些 shell 中,測試總是會失敗。不過,Ksh 和 Zsh 可以處理浮點數。


這就是運算符在 C中的工作方式,所有POSIXBashZsh都引用算術運算符的 C 定義。(POSIX 只定義$(( )), not (( )),但 Bash 和 Zsh 在兩者中對算術的處理方式相同。否則會令人困惑。)

一些較新的語言工作方式不同。Python,以友好著稱, 支持鍊式比較RustC++至少討論過添加類似的支持。就像那個 C++ 文件註釋一樣,無論如何,沒有人a < b < c在 C 意義上故意使用。(不過,類似的東西(a < b) != (c < d)可能有用。它會檢查其中一個關係是否為真。)Perl 和 GNU awk 似乎對1 < 2 < 3.

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