Bash 布尔测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23320150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:48:43  来源:igfitidea点击:

Bash Boolean testing

bash

提问by JLMarks

I am attempting to run a block of code if one flag is set to true and the other is set to false. ie

如果一个标志设置为 true 而另一个设置为 false,我将尝试运行一段代码。IE

var1=true
var2=false
if [[ $var1 && ! $var2 ]]; then var2="something"; fi

Since that did not evaluate the way that I expected I wrote several other test cases and I am having a hard time understanding how they are being evaluated.

由于这并没有按照我预期的方式进行评估,因此我编写了其他几个测试用例,并且我很难理解它们是如何被评估的。

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

When I run the preceding codeblock the only output I get is

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

Test0
Test0.1
Test0.2

Test0
Test0.1
Test0.2

however, my expectation is that I would get

然而,我的期望是我会得到

Test0
Test1
Test3
Test5
Test7

TEST0
的Test1
Test3的
TEST5
TEST7

I have tried to understand the best way to run similar tests, however most examples I have found are set up in the format of
if [[ "$aa" == true ]];
which is not quite what I want to do. So my question is what is the best way to make comparisons like this, and why do several of the test cases that I would expect to pass simply not?

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

Thank you!

谢谢!

回答by Ignacio Vazquez-Abrams

Without any operators, [[only checks if the variable is empty. If it is, then it is considered false, otherwise it is considered true. The contents of the variables do not matter.

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

回答by devnull

Your understanding of booleansin shell context is incorrect.

您对shell 上下文中布尔值的理解是不正确的。

var1=true
var2=false

Both the above variables are truesince those are non-empty strings.

上述两个变量都为真,因为它们是非空字符串

You could instead make use of arithmetic context:

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

$ 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

回答by Idriss Neumann

trueand falseare evaluated as strings ;)

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

[[ $var ]]is an equivalent of [[ -n $var ]]that check if $varis empty or not.

[[ $var ]]相当于[[ -n $var ]]检查是否$var为空。

Then, no need to quote your variables inside [[. See this reminder.

然后,无需在[[. 看到这个提醒

Finally, here is an explication of the difference between &&inside brackets and outside.

最后,这里解释了&&内括号和外括号之间的区别

回答by chepner

The shell does not have Boolean variables, per se. However, there are commandsnamed trueand falsewhose exit statuses are 0 and 1, respectively, and so can be used similarly to Boolean values.

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

var1=true
var2=false
if $var1 && ! $var2; then var2="something"; fi

The difference is that instead of testing if var1is set to a true value, you expand it to the name of a command, which runs and succeeds. Likewise, var2is expanded to a command name which runs and fails, but because it is prefixed with !the exit status is inverted to indicate success.

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

(Note that unlike most programming languages, an exit status of 0 indicates success because while most commands have 1 way to succeed, there are many different ways they could fail, so different non-zero values can be assigned different meanings.)

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

回答by Brandonian

The closest you can come seems to be use functions instead of variables because you can use their return status in conditionals.

最接近的似乎是使用函数而不是变量,因为您可以在条件中使用它们的返回状态。

$  var1() { return 0; }
$  var2() { return 1; }  # !0 = failure ~ false

and we can test this way

我们可以这样测试

$  var1 && echo "it's true" || echo "it's false"
it's true
$  var2 && echo "it's true" || echo "it's false"
it's false

or this way

或者这样

$  if var1; then echo "it's true"; else echo "it's false"; fi
it's true
$  if var2; then echo "it's true"; else echo "it's false"; fi
it's false

Hope this helps.

希望这可以帮助。