我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
当前回答
下面是一个适合我的简单例子:
temp1=true
temp2=false
if [ "$temp1" = true ] || [ "$temp2" = true ]
then
echo "Do something."
else
echo "Do something else."
fi
其他回答
博士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中,这样的操作是(在$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-}]](还有:没有“”,这对代码执行速度很重要!)
长话短说:
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 ...
我对(我自己的)愚蠢的看法:
# 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'
我发现现有的答案令人困惑。
就我个人而言,我只是想要一些看起来和工作起来像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