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

variable=$false

variable=$true

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

if [ $variable ]

if [ !$variable ]

当前回答

在大多数情况下,您需要“布尔”来执行布尔操作,例如!&&或||。在一些语言中,特殊的布尔类型根本不存在(因为实际上你在技术上不需要它),在大多数解释型语言中(几乎)所有类型在操作中自动转换为某种布尔类型,比如!&&或||。

布尔运算总是适用于布尔运算。在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-}]](还有:没有“”,这对代码执行速度很重要!)

其他回答

使用算术表达式。

#!/bin/bash

false=0
true=1

((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true

输出:

真正的 不是假的

下面是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"

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

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

你知道了。

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