HOWTO · Bash
在 Bash 中声明和使用布尔值
本教程演示了 Bash 中布尔值的声明和使用。
本页内容
Bash 没有专门的布尔变量类型。要表示一个选择,可以直接使用命令的成功或失败状态,也可以采用 1 表示启用、0 表示禁用之类的值约定。这是两种不同的概念:命令状态为 0 表示成功,非零表示失败。下面的示例展示如何分别使用这两种方式,而不把任意变量内容当作命令执行。
Bash 中的布尔值与退出状态
命令 true 和 false 分别表示成功和失败。if 语句判断的是它们的退出状态;它们是命令,不是存储在变量中的特殊值。需要存储某个值或将其作为参数传递时,脚本也可以使用有明确说明的整数标志。
在条件判断中使用 true 和 false
如果要判断的是某个命令成功还是失败,可以直接将该命令用作条件。这样 Bash 就会根据命令的退出状态选择执行分支。
本节中的代码以及显示的标签或输出仍为英文。
if true; then
printf '%s\n' 'The command succeeded.'
fi
if false; then
printf '%s\n' 'This branch is skipped.'
else
printf '%s\n' 'The command reported failure.'
fi
不要写成 if $value; then 来测试变量。Bash 会尝试把变量的内容作为命令运行。应改为比较已知值,或使用测试表达式。
在变量中表示类似布尔值的状态
整数标志属于应用程序约定,因此应选择并说明它的取值映射。此示例用 1 表示启用,0 表示禁用。算术条件会按数值比较该标志,不会将它与命令状态混为一谈。
运行此 Bash 示例,可以查看如何用数值检查启用标志、将它传给函数,以及用它控制循环输出。
本节中的代码以及显示的标签或输出仍为英文。
enabled=1
if (( enabled == 1 )); then
printf '%s\n' 'Feature is enabled.'
else
printf '%s\n' 'Feature is disabled.'
fi
report_feature() {
local flag=$1
if (( flag == 1 )); then
printf '%s\n' 'Function received an enabled flag.'
else
printf '%s\n' 'Function received a disabled flag.'
fi
}
report_feature "$enabled"
for item in alpha beta; do
if (( enabled == 1 )); then
printf 'Processing %s.\n' "$item"
fi
done
Feature is enabled.
Function received an enabled flag.
Processing alpha.
Processing beta.
检查文件时,应使用恰当的测试表达式。在 [ 测试中引用变量展开,避免值未设置或包含空白时改变测试参数。对于 Bash 专用条件,可以使用 [[ ... ]] 或算术语法。
使用逻辑运算符组合条件
只有左侧命令成功时,&& 才会运行右侧命令。左侧命令失败时,|| 才会运行右侧命令。因此,这两个运算符依据的都是命令状态,其中零表示成功。如果原本的分组方式不易读,可以加上括号,或拆成多个 if 语句。
本节中的代码以及显示的标签或输出仍为英文。
is_logged_in=1
is_admin=0
if (( is_logged_in == 1 && is_admin == 1 )); then
printf '%s\n' 'Access granted.'
else
printf '%s\n' 'Access denied.'
fi
config_file=/etc/example.conf
if [[ -f "$config_file" ]] && printf '%s\n' 'Configuration file exists.'; then
:
fi
第一个条件组合了两个整数标志。第二个条件会先检查文件,再打印提示信息;[[ -f ... ]] 是 Bash 条件表达式,不是会生成布尔变量的命令。
在函数和循环中使用标志
将明确定义的标志作为带引号的函数参数传入,然后按照相同的约定比较它。循环可以读取或更新该状态,以决定是否继续执行。应明确设置循环的停止条件,避免循环无限运行。
本节中的代码以及显示的标签或输出仍为英文。
keep_running=1
step=0
while (( keep_running == 1 )); do
(( step += 1 ))
printf 'Step %d.\n' "$step"
if (( step >= 3 )); then
keep_running=0
fi
done
算术命令会根据表达式的值返回状态。这里的递增量为正数,循环条件则使用已保存的标志,在计数器达到三时停止。
Bash 中常见的布尔值错误
- 不要认为 Bash 会把
0当作 true、把1当作 false。这是由你定义的取值约定;Shell 命令状态则以零表示成功,以非零表示失败。 - 不要通过将任意变量展开为命令来判断它是否为 true。应比较变量的值,或使用条件表达式。
- 在单中括号测试中引用变量展开,例如
[ "$name" = "ready" ]。对于数字,可以使用(( number == 1 )),或在数值测试中引用操作数。 - 请记住,
&&和||判断的是命令是否成功,而不是变量中存储的true或false这样的字词。
选择一种标志约定,并在赋值和比较时始终保持一致;需要判断某项操作是否成功时,则使用命令状态。