我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
修正答案(2014年2月12日)
the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
echo 'Be careful not to fall off!'
fi
原来的答案
警告:https://stackoverflow.com/a/21210966/89391
the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
echo 'Be careful not to fall off!'
fi
来自:在Bash中使用布尔变量
此处包含原答案的原因是,2014年2月12日修改前的评论仅涉及原答案,许多评论与修改后的答案相关联时是错误的。例如,Dennis Williamson在2010年6月2日关于bash builtin true的评论只适用于原始答案,而不适用于修改后的答案。
很久以前,当我们只有sh时,布尔值依赖于测试程序的约定来处理,在测试程序中,如果运行时不带任何参数,则返回错误的退出状态。
这允许人们认为一个未设置为false的变量和设置为任何值的变量为true。今天,test是Bash内置的,通常以它的一个字符别名[(或者在没有它的shell中使用的可执行文件,如dolmen所述)而为人所知:
FLAG="up or <set>"
if [ "$FLAG" ] ; then
echo 'Is true'
else
echo 'Is false'
fi
# Unset FLAG
# also works
FLAG=
if [ "$FLAG" ] ; then
echo 'Continues true'
else
echo 'Turned false'
fi
由于引号的约定,脚本作者更喜欢使用复合命令[[,它模仿test,但具有更好的语法:带空格的变量不需要被引用;可以使用&&和||作为具有奇怪优先级的逻辑运算符,并且没有POSIX对术语数量的限制。
例如,要确定是否设置了FLAG并且COUNT是一个大于1的数字:
FLAG="u p"
COUNT=3
if [[ $FLAG && $COUNT -gt '1' ]] ; then
echo 'Flag up, count bigger than 1'
else
echo 'Nope'
fi
当空格、零长度字符串和空变量都需要时,或者当脚本需要使用多个shell时,这些东西可能会令人困惑。
博士TL;
my_bool=true
if [ "$my_bool" = true ]
未来音乐(最初)的回答有问题
我不推荐公认的答案。它的语法很漂亮,但也有一些缺陷。
假设我们有以下条件。
if $var; then
echo 'Muahahaha!'
fi
在以下情况2中,此条件将计算为true并执行嵌套命令。
# Variable var not defined beforehand. Case 1
var='' # Equivalent to var="". # Case 2
var= # Case 3
unset var # Case 4
var='<some valid command>' # Case 5
通常,当你的“布尔”变量var显式设置为true时,你只希望你的条件值为true。其他所有的案例都是危险的误导!
最后一种情况(#5)特别淘气,因为它将执行变量中包含的命令(这就是为什么对于有效的command3,4,条件的计算结果为true)。
这里有一个无害的例子:
var='echo this text will be displayed when the condition is evaluated'
if $var; then
echo 'Muahahaha!'
fi
# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!
引用你的变量是更安全的,例如,if "$var";然后。在上述情况下,您应该得到一个警告,表示没有找到该命令。但我们仍然可以做得更好(见下面我的建议)。
也可以看看Mike Holt对Miku最初答案的解释。
赫巴的回答有问题
这种方法也有意想不到的行为。
var=false
if [ $var ]; then
echo "This won't print, var is false!"
fi
# Outputs:
# This won't print, var is false!
您可能期望上述条件的值为false,因此永远不会执行嵌套语句。惊喜!
引用值("false"),引用变量("$var"),或者使用test或[[而不是[,都没有区别。
我的建议是:
以下是我建议你检查“布尔值”的方法。他们按照预期工作。
my_bool=true
if [ "$my_bool" = true ]; then
if [ "$my_bool" = "true" ]; then
if [[ "$my_bool" = true ]]; then
if [[ "$my_bool" = "true" ]]; then
if [[ "$my_bool" == true ]]; then
if [[ "$my_bool" == "true" ]]; then
if test "$my_bool" = true; then
if test "$my_bool" = "true"; then
它们几乎都是一样的。与其他答案5中的方法相比,您将不得不输入更多的按键,但您的代码将更具防御性。
脚注
未来音乐的回答已被编辑,不再包含(已知的)缺陷。 这不是一个详尽的清单。 在此上下文中,有效命令是指存在的命令。命令使用正确或不正确并不重要。例如,man woman仍然被认为是一个有效的命令,即使没有这样的手册页存在。 对于无效的(不存在的)命令,Bash只会报错说没有找到该命令。 如果你关心长度,第一个建议是最短的。
这里似乎有一些关于Bash内置true的误解,更具体地说,关于Bash如何展开和解释括号内的表达式的误解。
miku回答中的代码与Bash内置的true,或/bin/true,或任何其他类型的true命令完全无关。在这种情况下,true只不过是一个简单的字符串,并且没有调用true命令/内置,无论是通过变量赋值,还是通过条件表达式求值。
下面的代码在功能上与miku回答中的代码相同:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
唯一不同的是,这里比较的四个字符是'y'、'e'、'a'和'h',而不是't'、'r'、'u'和'e'。就是这样。在Bash解析令牌true时,没有尝试调用名为yeah的命令或内置命令,(在miku的例子中)也没有任何特殊处理。它只是一个字符串,一个完全任意的字符串。
更新(2014-02-19):在看了miku回答中的链接后,现在我知道困惑来自哪里了。Miku的回答使用了单括号,但他链接的代码片段没有使用括号。它只是:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
这两个代码段将以相同的方式运行,但括号完全改变了底层的内容。
以下是Bash在每种情况下所做的事情:
没有括号:
将变量$the_world_is_flat展开为字符串“true”。 尝试将字符串“true”解析为命令。 找到并运行true命令(内置或/bin/true,取决于Bash版本)。 比较true命令的退出码(总是0)和0。回想一下,在大多数shell中,退出码为0表示成功,其他任何退出码都表示失败。 因为退出代码是0 (success),所以执行if语句的then子句
括号:
将变量$the_world_is_flat展开为字符串“true”。 解析现在完全展开的条件表达式,其形式为string1 = string2。=操作符是bash的字符串比较操作符。所以… 对"true"和"true"进行字符串比较。 是的,这两个字符串是一样的,所以条件的值为真。 执行if语句的then子句。
不带括号的代码可以工作,因为true命令返回一个退出代码0,表示成功。括号内的代码可以工作,因为$the_world_is_flat的值与=右边的字符串字面量true相同。
为了说明这一点,请考虑以下两段代码:
这段代码(如果以root权限运行)将重启您的计算机:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
这段代码只是打印出“Nice try”。没有调用reboot命令。
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
更新(2014-04-14)回答评论中关于=和==的区别的问题:AFAIK,没有区别。==操作符是特定于bash的=的同义词,据我所知,它们在所有上下文中的工作方式完全相同。
但是请注意,我特别讨论的是[]或[[]]测试中使用的=和==字符串比较运算符。我并不是说=和==在bash中到处都可以互换。
例如,你显然不能用==来做变量赋值,比如var=="foo"(技术上你可以这样做,但var的值将是"=foo",因为Bash在这里没有看到==运算符,它看到的是=(赋值)运算符,后面跟着字面值="foo",这就变成了"=foo")。
此外,虽然=和==是可互换的,但您应该记住,这些测试的工作方式取决于您是否在[]或[[]]中使用它,以及操作数是否被引用。您可以在高级Bash脚本指南:7.3其他比较操作符(向下滚动到=和==的讨论)中阅读更多相关内容。
与其伪造一个布尔值,给未来的读者留下一个陷阱,为什么不使用一个比真和假更好的值呢?
例如:
build_state=success
if something-horrible; then
build_state=failed
fi
if [[ "$build_state" == success ]]; then
echo go home; you are done
else
echo your head is on fire; run around in circles
fi
Bash确实将问题与[,[[,((,$((等))等混淆了。
所有人都在践踏彼此的代码空间。我想这主要是历史原因,巴什不得不偶尔装成。
大多数时候,我可以选择一种方法并坚持下去。在这种情况下,我倾向于声明(最好是在我可以包含的公共库文件中)。在我的实际脚本(s))。
TRUE=1; FALSE=0
然后我可以使用((…))算术运算符来测试。
testvar=$FALSE
if [[ -d ${does_directory_exist} ]]
then
testvar=$TRUE;
fi
if (( testvar == TRUE )); then
# Do stuff because the directory does exist
fi
你必须遵守纪律。你的testvar必须在任何时候都被设置为$TRUE或$FALSE。 在(……))比较器,你不需要前面的$,这使得它更可读。 我可以用(…)),因为$TRUE=1和$FALSE=0,即数值。 缺点是不得不偶尔使用$: 真正testvar = $ 这可不太好。
这不是一个完美的解决方案,但它涵盖了我需要这种测试的所有情况。
使用算术表达式。
#!/bin/bash
false=0
true=1
((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true
输出:
真正的 不是假的
我发现现有的答案令人困惑。
就我个人而言,我只是想要一些看起来和工作起来像C的东西。
这段代码在生产中每天工作多次:
snapshotEvents=true
if ($snapshotEvents)
then
# Do stuff if true
fi
为了让大家开心,我测试了:
snapshotEvents=false
if !($snapshotEvents)
then
# Do stuff if false
fi
这也很有效。
$snapshotEvents计算变量value的内容。所以你需要$。
你们其实不需要括号,我只是觉得它们很有用。
在GNU Bash, version 4.1.11(2)-release上测试 Bash初学者指南,Machtelt Garrels, v1.11, 2008
以下是对miku原始答案的改进,解决了Dennis Williamson对未设置变量的情况的担忧:
the_world_is_flat=true
if ${the_world_is_flat:-false} ; then
echo "Be careful not to fall off!"
fi
测试变量是否为false:
if ! ${the_world_is_flat:-false} ; then
echo "Be careful not to fall off!"
fi
关于变量中有讨厌内容的其他情况,这是任何外部输入馈送到程序的问题。
任何外部输入都必须在信任它之前进行验证。但是,当接收到输入时,这种验证只需要执行一次。
它不必像Dennis Williamson建议的那样,每次使用变量都这样做,从而影响程序的性能。
我如何在shell脚本中声明和使用布尔变量?
与许多其他编程语言不同,Bash不按“类型”隔离其变量。[1]
所以答案很明确。在Bash中没有任何布尔变量。
然而:
使用declare语句,可以将赋值限制为 变量。[2]
#!/bin/bash
declare -ir BOOL=(0 1) # Remember BOOL can't be unset till this shell terminates
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}
# Same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"
declare和readonly中的r选项用于显式声明变量为只读。我希望目的很明确。
Bill Parker被否决了,因为他的定义与正常的代码约定相反。通常,true被定义为0,false被定义为非0。1对false有效,9999和-1也一样。函数的返回值也是一样——0表示成功,任何非0表示失败。对不起,我还没有足够的街头信誉来投票或直接回复他。
Bash建议现在使用双括号而不是单括号作为一种习惯,Mike Holt给出的链接解释了它们工作方式的差异。7.3. 其他比较操作符
首先,-eq是一个数值运算符,所以有代码
#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
将发出错误语句,期望得到整数表达式。这适用于任意一个参数,因为两者都不是整数值。然而,如果我们在它周围加上双括号,它将不会发出错误声明,但它将产生一个错误的值(好吧,在50%的可能排列中)。它将计算为[[0 -eq true]] = success,但也计算为[[0 -eq false]] = success,这是错误的(嗯,....如果这个内置是一个数值呢?)
#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
还有其他的条件排列也会给出错误的输出。基本上,将一个变量设置为数值并将其与一个真/假的内置变量进行比较,或者将一个变量设置为真/假的内置变量并将其与一个数值进行比较的任何事情(上面列出的错误条件除外)。此外,任何将一个变量设置为true/false的内置变量,并使用-eq进行比较。所以避免使用-eq进行布尔比较,避免使用数值进行布尔比较。下面是会产生无效结果的排列的总结:
# With variable set as an integer and evaluating to true/false
# *** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
# With variable set as an integer and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then
# With variable set as an true/false builtin and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then
那么,现在来看看什么是有效的。在比较和计算时使用真/假内置参数(Mike Hunt指出,不要用引号括起来)。然后使用一个或一个或两个等号(=或==)和一个或两个括号([]或[[]])。就我个人而言,我喜欢双等号,因为它让我想起了其他编程语言中的逻辑比较,而双引号只是因为我喜欢打字。所以这些工作:
# With variable set as an integer and evaluating to true/false
# *** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then
你知道了。
长话短说:
Bash中没有布尔值
true和false命令
Bash确实有比较和条件方面的布尔表达式。也就是说,在Bash中可以声明和比较的是字符串和数字。就是这样。
无论你在Bash中看到真或假,它要么是一个字符串,要么是一个命令/内置,它只用于退出代码。
这语法…
if true; then ...
本质上是…
if COMMAND; then ...
其中命令为true。当命令返回退出代码0时,条件为真。true和false是Bash内置的,有时也是独立的程序,它们什么都不做,只返回相应的退出码。
条件在if..then..fi
当使用方括号或test命令时,您依赖于该构造的退出代码。请记住,[]和[[]]也像其他命令一样只是命令/内置程序。所以…
if [[ 1 == 1 ]]; then echo yes; fi
对应于
if COMMAND; then echo yes; fi
这里的COMMAND是[[参数为1 == 1]]
如果…那么…Fi构念只是语法糖。你可以用双&号分隔命令来运行同样的效果:
[[ 1 == 1 ]] && echo yes
当在这些测试结构中使用true和false时,您实际上只是将字符串“true”或“false”传递给测试命令。这里有一个例子:
信不信由你,但这些条件都产生了相同的结果:
if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...
TL,博士;总是与字符串或数字进行比较
为了让未来的读者更清楚地了解这一点,我建议在真假周围使用引号:
DO
if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ "${var}" == "yes" ]]; then ...
if [[ "${var}" == "USE_FEATURE_X" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...
不
# Always use double square brackets in bash!
if [ ... ]; then ...
# This is not as clear or searchable as -n
if [[ "${var}" ]]; then ...
# Creates impression of Booleans
if [[ "${var}" != true ]]; then ...
# `-eq` is for numbers and doesn't read as easy as `==`
if [[ "${var}" -eq "true" ]]; then ...
也许
# Creates impression of Booleans.
# It can be used for strict checking of dangerous operations.
# This condition is false for anything but the literal string "true".
if [[ "${var}" != "true" ]]; then ...
下面是一个适合我的简单例子:
temp1=true
temp2=false
if [ "$temp1" = true ] || [ "$temp2" = true ]
then
echo "Do something."
else
echo "Do something else."
fi
POSIX(便携式操作系统接口)
我忽略了关键的一点,那就是便携性。这就是为什么我的头文件本身有POSIX。
基本上,所有投票的答案都是正确的,除了它们太特定于bash之外。
基本上,我只想添加更多关于可移植性的信息。
像["$var" = true]中的[和]括号是不必要的,你可以省略它们,直接使用test命令: test "$var" = true && yourCodeIfTrue || yourCodeIfFalse 重要提示:我不再推荐这种方法,因为它正在慢慢被弃用,而且组合多个语句更加困难。 想象一下这些单词true和false对shell意味着什么,自己测试一下: Echo $((true)) 0 Echo $((false)) 1 但是使用引号: Echo $(("true")) Bash: "true":语法错误:操作数预期(错误令牌是"true") Sh(破折号):Sh: 1:算术表达式:期望主:""true"" 这同样适用于: Echo $(("false")) shell只能解释一个字符串。我希望你的想法是多么好的使用适当的关键字没有引号。 但在之前的回答中没有人这么说。 这是什么意思?嗯,有几件事。 你应该习惯布尔关键字实际上被视为数字,即true = 0和false = 1,记住所有非零值都被视为false。 因为它们被视为数字,你也应该这样对待它们,即如果你定义变量说: var_bool = true 回声“var_bool美元” 真正的 你可以用以下方法创建它的相反值: Var_bool =$((1 - $ Var_bool)) #与$((!美元var_bool)) 回声“var_bool美元” 1 正如您自己所看到的,shell在您第一次使用它时确实打印了true字符串,但从那以后,它都分别通过数字0表示true或1表示false来工作。
最后,你应该如何处理所有这些信息
首先,一个好习惯是赋值0而不是true;1而不是false。 第二个好习惯是测试变量是否等于0: If ["$var_bool" -eq 0];然后 yourCodeIfTrue 其他的 yourCodeIfFalse fi
下面是if为true的一个实现。
# Function to test if a variable is set to "true"
_if () {
[ "${1}" == "true" ] && return 0
[ "${1}" == "True" ] && return 0
[ "${1}" == "Yes" ] && return 0
return 1
}
示例1
my_boolean=true
_if ${my_boolean} && {
echo "True Is True"
} || {
echo "False Is False"
}
示例2
my_boolean=false
! _if ${my_boolean} && echo "Not True is True"
在许多编程语言中,布尔类型是或被实现为整数的子类型,其中true表现为1,false表现为0:
C语言中的布尔值 Python中的布尔值 Java中的布尔值
数学上,布尔代数类似于整数模数2。因此,如果一种语言不提供本机布尔类型,最自然和有效的解决方案是使用整数。这几乎适用于任何语言。例如,在Bash中,你可以这样做:
# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false
男人bash:
(表达) 表达式根据下面算术求值部分描述的规则求值。如果表达式的值非0,则返回状态为0;否则返回状态为1。这完全等价于let“expression”。
我的发现和建议与其他帖子有所不同。我发现我可以像使用任何“常规”语言一样使用“布尔值”,而不需要“跳篮”……
不需要使用[]或显式的字符串比较…我尝试了多个Linux发行版。我测试了Bash、Dash和BusyBox。结果总是一样的。我不确定最初投票最多的帖子在谈论什么。也许时代变了,就是这样?
如果将一个变量设置为true,它随后会在条件中作为“肯定”进行计算。将其设置为false,它的计算结果为“负”。很简单的!唯一需要注意的是,未定义的变量的计算结果也类似于true!如果它做了相反的事情(就像在大多数语言中那样),那就好了,但这就是诀窍——你只需要显式地将你的布尔值初始化为true或false。
为什么会这样?答案是双重的。A) true/false在shell中实际上意味着“无错误”vs“错误”(即0 vs任何其他)。B) true/false不是值——而是shell脚本中的语句!关于第二点,在一行中执行true或false本身就设置了你所在块的返回值,即false是“遇到错误”的声明,而true则“清除”该值。将它与对变量的赋值一起使用,将其“返回”到变量中。一个未定义的变量在条件句中的计算结果类似于true,因为它同样表示0或“没有遇到错误”。
请参阅下面的示例Bash行和结果。如果你想确认,自己测试一下…
#!/bin/sh
# Not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;
收益率
when set to
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false
你可以使用shFlags。
它为您提供了定义:DEFINE_bool的选项
例子:
DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
在命令行中你可以定义:
sh script.sh --bigmenu
sh script.sh --nobigmenu # False
替代-使用函数
is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It's OK" || echo "Something's wrong"
定义函数不那么直观,但是检查它的返回值非常容易。
这是一个关于在Bash中测试“布尔”值的不同方法的速度测试:
#!/bin/bash
rounds=100000
b=true # For true; b=false for false
type -a true
time for i in $(seq $rounds); do command $b; done
time for i in $(seq $rounds); do $b; done
time for i in $(seq $rounds); do [ "$b" == true ]; done
time for i in $(seq $rounds); do test "$b" == true; done
time for i in $(seq $rounds); do [[ $b == true ]]; done
b=x; # Or any non-null string for true; b='' for false
time for i in $(seq $rounds); do [ "$b" ]; done
time for i in $(seq $rounds); do [[ $b ]]; done
b=1 # Or any non-zero integer for true; b=0 for false
time for i in $(seq $rounds); do ((b)); done
它会打印出
true is a shell builtin
true is /bin/true
real 0m0,815s
user 0m0,767s
sys 0m0,029s
real 0m0,562s
user 0m0,509s
sys 0m0,022s
real 0m0,829s
user 0m0,782s
sys 0m0,008s
real 0m0,782s
user 0m0,730s
sys 0m0,015s
real 0m0,402s
user 0m0,391s
sys 0m0,006s
real 0m0,668s
user 0m0,633s
sys 0m0,008s
real 0m0,344s
user 0m0,311s
sys 0m0,016s
real 0m0,367s
user 0m0,347s
sys 0m0,017s
关于语法,这是一个简单的方法,我使用(通过例子)来一致和理智地管理布尔逻辑:
# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc
if [[ -n "${var}" ]] ; then
echo 'true'
fi
if [[ -z "${var}" ]] ; then
echo 'false'
fi
# Results
# var= # false
# var='' # false
# var="" # false
# var=0 # true
# var=1 # true
# var="abc" # true
# var=abc # true
如果变量从未被声明,答案是:# false
因此,将变量设置为true(使用这种语法方法)的简单方法是,var=1;相反,var = "。
参考:
如果var字符串的长度非零,则-n = True。
如果var字符串的长度为零,则-z = True。
我对(我自己的)愚蠢的看法:
# setting ----------------
commonMode=false
if [[ $something == 'COMMON' ]]; then
commonMode=true
fi
# using ----------------
if $commonMode; then
echo 'YES, Common Mode'
else
echo 'NO, no Common Mode'
fi
$commonMode && echo 'commonMode is ON ++++++'
$commonMode || echo 'commonMode is OFF xxxxxx'
使用布尔值的另一种方法是测试值是否为空。这样做的好处是可以进行更短的测试:
first=1 # A true value
second= # A false value
[ -n "$first" ] && echo 'First var is true'
[ -z "$first" ] && echo 'First var is false'
[ -n "$second" ] && echo 'Second var is true'
[ -z "$second" ] && echo 'Second var is false'
输出:
First var is true
Second var is false
下面是bash的另一个测试语法:[[-n $one]]
在大多数情况下,您需要“布尔”来执行布尔操作,例如!&&或||。在一些语言中,特殊的布尔类型根本不存在(因为实际上你在技术上不需要它),在大多数解释型语言中(几乎)所有类型在操作中自动转换为某种布尔类型,比如!&&或||。
布尔运算总是适用于布尔运算。在Bash中,这样的操作是(在$var周围没有“”,这非常重要!):
[[ $var ]] - check if var is true
[[ ! $var ]] - check if var is false
[[ $var1 || $var2 ]] - var1 or var2
[[ $var1 && $var2 ]] - var1 and var2
[[$var]]仅当var= "(或未设置)时为false。所以唯一一个正确的“假”值的变量在bash是“(空字符串)。对于true,你可以选择任何值,但我更喜欢var=1(就像在其他语言中,true是任何非null int,但出于可读性的目的,程序员总是使用1)。
注意:对于var='false', var在布尔检查中为真。在Bash中字符串'false'实际上是true(与所有其他语言相同!)。Bash和Python、Perl或PHP之间唯一的区别是,在Bash 0中也是如此。但是,Bash中也有布尔运算,它们的工作原理和所有其他解释语言一样,除了Bash中的0为真。
在Bash中使用字符串'true'和'false'作为布尔替换是绝对不合理的。这就像在Python、Perl或PHP中使用相同的奇怪概念一样。它的工作速度较慢(在Bash中也是如此),没有人在其他语言中这样做,但在Bash中有很多程序员认为这是一个很好的解决方案。不。在Bash中没有理由不直接使用布尔运算,没有像$var == 'true'或$var == 'false'这样绝对奇怪的比较。
再次强调,Bash中的布尔替换是:
var='' # false
var=1 # true (actually any non-empty string)
在Bash中直接使用布尔检查也是执行类布尔检查的最快方法。所有其他结构都要慢得多。
注:“旧”风格的“布尔”检查像a=true;如果美元;然后……绝对是白痴,因为:
不能在[[]]条件下直接使用 它们充当bash代码的eval,存储在变量中。好吧,如果你认为这是个好主意,请不要写任何程序;)
P.P.S.如果$var可以取消设置,并且你使用了非常有用的set -u,只需在检查中将$var替换为${var-},例如[[${var-}]](还有:没有“”,这对代码执行速度很重要!)