我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
我尝试在shell脚本中使用以下语法声明一个布尔变量:
variable=$false
variable=$true
这对吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,下面使用布尔变量作为表达式的语法正确吗?
if [ $variable ]
if [ !$variable ]
当前回答
关于语法,这是一个简单的方法,我使用(通过例子)来一致和理智地管理布尔逻辑:
# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc
if [[ -n "${var}" ]] ; then
echo 'true'
fi
if [[ -z "${var}" ]] ; then
echo 'false'
fi
# Results
# var= # false
# var='' # false
# var="" # false
# var=0 # true
# var=1 # true
# var="abc" # true
# var=abc # true
如果变量从未被声明,答案是:# false
因此,将变量设置为true(使用这种语法方法)的简单方法是,var=1;相反,var = "。
参考:
如果var字符串的长度非零,则-n = True。
如果var字符串的长度为零,则-z = True。
其他回答
我如何在shell脚本中声明和使用布尔变量?
与许多其他编程语言不同,Bash不按“类型”隔离其变量。[1]
所以答案很明确。在Bash中没有任何布尔变量。
然而:
使用declare语句,可以将赋值限制为 变量。[2]
#!/bin/bash
declare -ir BOOL=(0 1) # Remember BOOL can't be unset till this shell terminates
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}
# Same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"
declare和readonly中的r选项用于显式声明变量为只读。我希望目的很明确。
在大多数情况下,您需要“布尔”来执行布尔操作,例如!&&或||。在一些语言中,特殊的布尔类型根本不存在(因为实际上你在技术上不需要它),在大多数解释型语言中(几乎)所有类型在操作中自动转换为某种布尔类型,比如!&&或||。
布尔运算总是适用于布尔运算。在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-}]](还有:没有“”,这对代码执行速度很重要!)
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
你知道了。
关于语法,这是一个简单的方法,我使用(通过例子)来一致和理智地管理布尔逻辑:
# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc
if [[ -n "${var}" ]] ; then
echo 'true'
fi
if [[ -z "${var}" ]] ; then
echo 'false'
fi
# Results
# var= # false
# var='' # false
# var="" # false
# var=0 # true
# var=1 # true
# var="abc" # true
# var=abc # true
如果变量从未被声明,答案是:# false
因此,将变量设置为true(使用这种语法方法)的简单方法是,var=1;相反,var = "。
参考:
如果var字符串的长度非零,则-n = True。
如果var字符串的长度为零,则-z = True。
很久以前,当我们只有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时,这些东西可能会令人困惑。