我尝试在shell脚本中使用以下语法声明一个布尔变量:

variable=$false

variable=$true

这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?

if [ $variable ]

if [ !$variable ]

当前回答

博士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只会报错说没有找到该命令。 如果你关心长度,第一个建议是最短的。

其他回答

在许多编程语言中,布尔类型是或被实现为整数的子类型,其中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

以下是对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建议的那样,每次使用变量都这样做,从而影响程序的性能。

[[ "$x" == 'true' || "$x" -ne 0 ]] && ...

足够简单并且没有依赖项。

修正答案(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的评论只适用于原始答案,而不适用于修改后的答案。