我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
当前回答
很久以前,当我们只有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时,这些东西可能会令人困惑。
其他回答
使用算术表达式。
#!/bin/bash
false=0
true=1
((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true
输出:
真正的 不是假的
[[ "$x" == 'true' || "$x" -ne 0 ]] && ...
足够简单并且没有依赖项。
很久以前,当我们只有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时,这些东西可能会令人困惑。
替代-使用函数
is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It's OK" || echo "Something's wrong"
定义函数不那么直观,但是检查它的返回值非常容易。
长话短说:
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 ...