vis*_*360 3 zsh shell-script arithmetic
为什么将 0 作为参数传递会导致误报(打印“True”)?
#!/bin/zsh
k="$1"
if ((0 < k < 1))
then
echo "True"
fi
Run Code Online (Sandbox Code Playgroud)
注意这个脚本被称为stitch_applier.sh
终端
% ./stitch_applier.sh 0
True
Run Code Online (Sandbox Code Playgroud)
这是在 Linux 系统上运行的。
ilk*_*chu 10
shell 的算法不支持这样的链式比较。相反,第一个a < b
返回1
或0
,具体取决于关系是否为真。
因此,如果k
是0
,则((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 中的工作方式,所有POSIX、Bash和Zsh 都引用算术运算符的 C 定义。(POSIX 只定义了$(( ))
,not (( ))
,但是 Bash 和 Zsh 在这两者中对算术的处理是相同的。否则会造成混淆。)
一些较新的语言的工作方式有所不同。Python 以友好着称, 支持链式比较,Rust和C++至少讨论过添加类似的支持。就像 C++ 文档注释一样,无论如何都没有人a < b < c
故意使用C 语言。(不过,类似的东西(a < b) != (c < d)
可能有用。它会检查其中一个关系是否为真。)Perl 和 GNU awk 似乎给出了1 < 2 < 3
.