Bash布尔测试

JLM*_*rks 13 bash

我试图运行一个代码块,如果一个标志设置为true而另一个标志设置为false.即

var1=true
var2=false
if [[ $var1 && ! $var2 ]]; then var2="something"; fi
Run Code Online (Sandbox Code Playgroud)

由于这没有评估我预期的方式,我写了几个其他的测试用例,我很难理解他们是如何被评估的.

aa=true 
bb=false
cc="python"
if [[ "$aa" ]]; then echo "Test0" ; fi
if [[ "$bb" ]]; then echo "Test0.1" ; fi
if [[ !"$aa" ]]; then echo "Test0.2" ; fi
if [[ ! "$aa" ]]; then echo "Test0.3" ; fi
if [[ "$aa" && ! "$bb" ]]; then echo "Test1" ; fi
if [[ "$aa" && ! "$aa" ]]; then echo "Test2" ; fi
if [[ "$aa" ]] && ! [[ "$bb" ]]; then echo "test3" ; fi
if [[ "$aa" ]] && ! [[ "$cc" ]]; then echo "test4" ; fi
if [[ $aa && ! $bb ]]; then echo "Test5" ; fi
if [[ $aa && ! $aa ]]; then echo "Test6" ; fi
if [[ $aa ]] && ! [[ $bb ]]; then echo "test7" ; fi
if [[ $aa ]] && ! [[ $cc ]]; then echo "test8" ; fi
Run Code Online (Sandbox Code Playgroud)

当我运行前面的代码块时,我得到的唯一输出是

Test0
Test0.1
Test0.2

但是,我的期望是我会得到

Test0
Test1
Test3
Test5
Test7

我试图理解运行类似测试的最佳方法,但是我发现的大多数例子都是以
if [["$ aa"== true]] 的格式设置的;
这不是我想要做的.所以我的问题是进行这种比较的最佳方法是什么,以及为什么我希望通过的几个测试用例根本没有?

谢谢!

Ign*_*ams 14

没有任何运算符,[[只检查变量是否为空.如果是,那么它被认为是假的,否则它被认为是真的.变量的内容无关紧要.


dev*_*ull 14

您对shell语境中的布尔值的理解是不正确的.

var1=true
var2=false
Run Code Online (Sandbox Code Playgroud)

以上两个变量都是正确的,因为它们是非空字符串.

您可以改为使用算术上下文:

$ a=1
$ b=0
$ ((a==1 && b==0)) && echo y
y
$ ((a==0 && b==0)) && echo y
$
$ ((a && !(b))) && echo y;       # This seems to be analogous to what you were attempting
y
Run Code Online (Sandbox Code Playgroud)

  • 您可以将其与 readonly true=1 yes=1 no=0 false=0 结合起来,为算术表达式中的 true 和 false 创建可靠的常量。 (2认同)

che*_*ner 8

外壳本身没有布尔变量。但是,有一些命令命名truefalse退出状态分别为 0 和 1,因此可以与布尔值类似地使用。

var1=true
var2=false
if $var1 && ! $var2; then var2="something"; fi
Run Code Online (Sandbox Code Playgroud)

不同之处在于,不是测试 ifvar1是否设置为真值,而是将其扩展为命令的名称,该命令运行并成功。同样,var2扩展为运行并失败的命令名称,但由于它以!退出状态为前缀,因此被反转以指示成功。

(请注意,与大多数编程语言不同,退出状态 0 表示成功,因为虽然大多数命令有 1 种成功方式,但它们可能会以多种不同方式失败,因此可以为不同的非零值分配不同的含义。)


Idr*_*ann 6

true并被false评估为字符串;)

[[ $var ]][[ -n $var ]]如果$var是空的,则相当于该检查.

然后,不需要在里面引用你的变量[[.看到此提醒.

最后,这里是&&内部括号和外部之间差异的解释.