bash“;如果[假]&引用;返回true而不是false——为什么?
为什么以下输出bash“;如果[假]&引用;返回true而不是false——为什么?,bash,boolean,conditional-operator,Bash,Boolean,Conditional Operator,为什么以下输出为True #!/bin/sh if [ false ]; then echo "True" else echo "False" fi 这将始终输出True,即使条件似乎另有指示。如果我删除括号[],它会工作,但我不明白为什么。您正在运行参数为“false”的[(又称test)命令,而不是运行命令false。因为“false”是非空字符串,test命令始终成功。若要实际运行该命令,请删除[命令 if false; then
为True
#!/bin/sh
if [ false ]; then
echo "True"
else
echo "False"
fi
这将始终输出
True
,即使条件似乎另有指示。如果我删除括号[]
,它会工作,但我不明白为什么。您正在运行参数为“false”的[
(又称test
)命令,而不是运行命令false
。因为“false”是非空字符串,test
命令始终成功。若要实际运行该命令,请删除[
命令
if false; then
echo "True"
else
echo "False"
fi
我发现我可以通过运行以下程序来实现一些基本逻辑:
A=true
B=true
if ($A && $B); then
C=true
else
C=false
fi
echo $C
使用true/false可以删除一些括号混乱
#! /bin/bash
# true_or_false.bash
[ "$(basename $0)" == "bash" ] && sourced=true || sourced=false
$sourced && echo "SOURCED"
$sourced || echo "CALLED"
# Just an alternate way:
! $sourced && echo "CALLED " || echo "SOURCED"
$sourced && return || exit
Bash的快速布尔入门
if语句将命令作为参数(如&
、|
等)。命令的整数结果代码被解释为布尔值(0/null=true,1/else=false)
test
语句将运算符和操作数作为参数,并以与if
相同的格式返回结果代码。test
语句的别名是[
,通常与if
一起使用,以执行更复杂的比较
true
和false
语句不起任何作用,返回结果代码(分别为0和1)。因此它们可以在Bash中用作布尔文本。但是如果将语句放在解释为字符串的位置,则会遇到问题。在您的情况下:
if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ... # "if the command foo succeeds, return true"
因此:
这类似于执行类似于echo'$foo'
与echo“$foo”
的操作
使用test
语句时,结果取决于使用的运算符。
if [ "$foo" = "$bar" ] # true if the string values of $foo and $bar are equal
if [ "$foo" -eq "$bar" ] # true if the integer values of $foo and $bar are equal
if [ -f "$foo" ] # true if $foo is a file that exists (by path)
if [ "$foo" ] # true if $foo evaluates to a non-empty string
if foo # true if foo, as a command/subroutine,
# evaluates to true/success (returns 0 or null)
简而言之,如果您只想测试通过/失败(也称为“真”/“假”),则将命令传递给if
或&&
等语句,不带括号。对于复杂的比较,请使用括号和适当的运算符
是的,我知道Bash中没有原生布尔类型,而且
if
和[
和true
在技术上是“命令”而不是“语句”;这只是一个非常基本的、功能性的解释。添加上下文,希望有助于在这个主题上提供一点额外的清晰性。对于BaSH新手来说,它对真/假陈述的感觉相当奇怪。以下面的简单示例及其结果为例
此语句将返回“true”:
但这将返回“false”:
你明白为什么了吗?第一个例子有一个带引号的“”字符串。这会导致BaSH逐字处理它。因此,在字面意义上,空格不是null。而在非字面意义上(上面的第二个例子),BaSH将空格(作为$foo中的值)视为“nothing”,因此它等同于null(此处解释为“false”)
这些语句都将返回一个文本字符串“false”:
有趣的是,这种类型的条件将始终返回true:
foo=" "; if [ "$foo" ]; then echo "true"; else echo "false"; fi
这些语句都将返回“true”的结果:
请注意差异;在条件中变量名前面省略了$符号。在括号之间插入什么单词无关紧要。BaSH始终会将此语句视为true,即使您使用的单词以前从未与同一shell中的变量关联
if [ sooperduper ]; then echo "true"; else echo "false"; fi
同样,将其定义为未声明的变量可确保其始终返回false:
foo=" "; if [ $foo ]; then echo "true"; else echo "false"; fi
if [ $sooperduper ]; then echo "true"; else echo "false"; fi
if [ $foo ]; then echo "true"; else echo "false"; fi
if [ ! foo ]; then echo "true"; else echo "false"; fi
至于BaSH,这与写:
sooperduper="";if [ $sooperduper ]; then echo "true"; else echo "false"; fi
还有一个提示 括号与无括号的比较 更令人困惑的是,IF/THEN条件的这些变化都起作用,但返回相反的结果 这些返回值为false:
foo=" "; if [ $foo ]; then echo "true"; else echo "false"; fi
if [ $sooperduper ]; then echo "true"; else echo "false"; fi
if [ $foo ]; then echo "true"; else echo "false"; fi
if [ ! foo ]; then echo "true"; else echo "false"; fi
但是,这些将返回true的结果:
foo=""; if [ foo ]; then echo "true"; else echo "false"; fi
if $foo; then echo "true"; else echo "false"; fi
if [ foo ]; then echo "true"; else echo "false"; fi
if [ ! $foo ]; then echo "true"; else echo "false"; fi
当然,这会返回一个语法错误(以及“false”的结果):
还不明白吗?一开始就想清楚这一点是很有挑战性的,特别是如果你习惯了其他更高级的编程语言。正如@tripleee所指出的,这充其量是相切的 不过,如果你到这里来寻找类似的东西(就像我做的那样),这里是我的解决方案 由于必须处理用户可访问的配置文件,我使用此功能:
function isTrue() {
if [[ "${@^^}" =~ ^(TRUE|OUI|Y|O$|ON$|[1-9]) ]]; then return 0;fi
return 1
}
wich可以这样使用
if isTrue "$whatever"; then..
您可以更改regexp中的“真值列表”,此示例中的列表与法语兼容,并将“Yeah,yup,on,1,Oui,y,true”等字符串视为“真”
请注意,“^^”提供了不区分大小写的功能。顺便说一句,以
#!/bin/sh
开头的脚本不是bash脚本,而是POSIX sh脚本。即使系统上的POSIX sh解释器是由bash提供的,它也会关闭一系列扩展。如果要编写bash脚本,请使用#!/bin/bash
或其本地相应的等价物(#!/usr/bin/env bash
使用路径中的第一个bash解释器)。这会影响[[false]]
也是。false是一个命令,甚至是一个字符串的想法对我来说似乎很奇怪,但我猜它是有效的。谢谢。bash
没有布尔数据类型,因此没有表示true和false的关键字。if
语句只检查您发出的命令是否成功。test
命令接受一个表达式,然后执行如果表达式为true,则为cceeds;与大多数其他编程语言一样,非空字符串是一个计算结果为true的表达式。false
是一个总是失败的命令。true
是一个总是成功的命令。if[[false]];
也返回true。if[[0]]如果[/usr/bin/false]];
也不跳过该块,那么怎么能将false或0计算为非零?该死的,这太令人沮丧了。如果重要的话,OS X 10.8;Bash 3。不要搞错false