How to declare and use boolean variables in shell script?
我尝试使用以下语法在shell脚本中声明布尔变量:
1 2 3 | variable=$false variable=$true |
这是正确的吗?另外,如果我想更新这个变量,我会使用相同的语法吗?最后,使用布尔变量作为表达式的语法是否正确:
1 2 3 | if [ $variable ] if [ !$variable ] |
答案(2月12日,2014年修订)
1 2 3 4 5 | the_world_is_flat=true # ...do something interesting... if ["$the_world_is_flat" = true ] ; then echo 'Be careful not to fall off!' fi |
原始的答案
警告:http:/ / / / / 89391 21210966 stackoverflow.com
1 2 3 4 5 | 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日,pertain只原始的答案,和许多的评论是错误的,当与修订相关的答案。例如,丹尼斯威廉姆森的评论关于bash builtin
铊;博士
1 2 3 | bool=true if ["$bool" = true ] |
未来的问题和答案(原创)
我不建议answer1公认。它的语法是漂亮的,但它有一些获得。
说我们有下面的状态。
1 2 3 | if $var; then echo 'Muahahaha!' fi |
在下面的cases2状态评估,这是真正的和想的嵌套执行的命令。
1 2 3 4 5 | # 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 |
通常你想你真当你评估一个状态变量
最后的案例(特别是顽皮的# 5),因为它要执行的命令中包含的变量(这就是为什么一个有效状态evaluates为commands3,4)。
这里是一个例子:无害的
1 2 3 4 5 6 7 8 | 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! |
引证你的变量是安全的,例如
所以迈克解释海浩特初音的原版的答案。
问题的答案在HBAR
因此,本方法有意外的行为。
1 2 3 4 5 6 7 | var=false if [ $var ]; then echo"This won't print, var is false!" fi # Outputs: # This won't print, var is false! |
你会期望上述状态评估是假,因此不执行循环中的语句。惊喜!
引证的值(
我所做的是:
这是我建议你检查你的方式"booleans"。他们的工作是可能的。
1 2 3 4 5 6 7 8 9 10 11 12 | bool=true if ["$bool" = true ]; then if ["$bool" ="true" ]; then if [["$bool" = true ]]; then if [["$bool" ="true" ]]; then if [["$bool" == true ]]; then if [["$bool" =="true" ]]; then if test"$bool" = true; then if test"$bool" ="true"; then |
他们所有的当量相当多。你有一个keystrokes型更多的方法比其他的answers5但代码将更多的防守。
脚注
这里似乎有一些关于bash内置的
Miku答案中的代码与bash内置的
以下代码在功能上与Miku答案中的代码相同:好的。
1 2 3 4 | the_world_is_flat=yeah if ["$the_world_is_flat" = yeah ]; then echo 'Be careful not to fall off!' fi |
这里唯一的区别是要比较的四个字符是"y"、"e"、"a"和"h",而不是"t"、"r"、"u"和"e"。就是这样。没有试图调用名为
更新(2014-02-19):在跟踪了Miku答案中的链接之后,现在我看到了一些混乱的来源。Miku的答案使用单括号,但他链接到的代码片段不使用括号。只是:好的。
1 2 3 4 | the_world_is_flat=true if $the_world_is_flat; then echo 'Be careful not to fall off!' fi |
这两个代码片段的行为方式相同,但括号完全改变了引擎盖下的情况。好的。
下面是bash在每种情况下所做的工作:好的。
无括号:好的。
括号:好的。
无括号代码可以工作,因为
只需考虑以下两个代码片段,就可以将这一点带回家:好的。
此代码(如果使用根权限运行)将重新启动计算机:好的。
1 2 3 4 | var=reboot if $var; then echo 'Muahahaha! You are going down!' fi |
这段代码只是打印"很好的尝试"。没有调用reboot命令。好的。字母名称(P)Update(2014-04-14)to answer the question in the comments regarding the difference between EDOCX1 penal 0 and EDOCX1 penal 1:afaik,there is no difference.The EDOCX1 commercial operator is a bash-specific synonym for EDOCX1 original 0,and as far as I've seen,they work exactly the same in all context.好的,好的。(P)Note,however,that I'm specifically talking about the EDOCX1 penal 0 and EDOCX1 penal 1 string comparison operators used in either EDOCX1 penalthy 6I'm not suggesting that EDOCX1 plography 0 ocol and EDOCX1 plus 1 is interchangeable everywhere in Bash.好的,好的。(P)For example,you obviously can't do variable assignment with EDOCX1 commercial,such as EDOCX1 commercial 11(well technically you can do this,but the value of EDOCX1 individual 12 commercial will be EDOCX1 13 commercial,because bash isn't seeing an EDOCX1Ch just becomes
使用算术表达式。
1 2 3 4 5 6 7 8 9 | #!/bin/bash false=0 true=1 ((false)) && echo false ((true)) && echo true ((!false)) && echo not false ((!true)) && echo not true |
输出:
true
not false
长话短说:
巴什没有布尔人bash所具有的,是在比较和条件方面的布尔表达式。也就是说,可以在bash中声明和比较的是字符串和数字。就是这样。
在bash中,无论您在何处看到
这个语法…
1 | if true; then ... |
本质上是…
1 | if COMMAND; then ... |
当命令返回退出代码0时,条件为真。
上述条件相当于:
1 | COMMAND && ... |
当使用方括号或
1 | if [[ 1 == 1 ]]; then echo yes; fi |
对应于
1 | if COMMAND; then echo yes; fi |
这是
1 | [[ 1 == 1 ]] && echo yes |
在这些测试结构中使用
信不信由你,但这些条件都会产生同样的结果:
1 2 3 4 | if [[ false ]]; then ... if [["false" ]]; then ... if [[ true ]]; then ... if [["true" ]]; then ... |
总是与字符串或数字比较
为了向未来的读者阐明这一点,我建议始终使用围绕
1 2 3 | if [["${var}" =="true" ]]; then ... if [["${var}" =="false" ]]; then ... if [[ -n"${var:-}" ]]; then echo"var is not empty" ... |
不要
1 2 3 4 | if [ ... ]; then ... # always use double square brackets in bash! if [["${var}" ]]; then ... # this is not as clear or searchable as -n if [["${var}" != true ]]; then ... # creates impression of booleans if [["${var}" -eq"true" ]]; then ... # `-eq` is for numbers and doesn't read as easy as `==` |
也许吧
1 | if [["${var}" !="true" ]]; then ... # creates impression of booleans. Can be used for strict checking of dangerous operations. This condition is false for anything but the literal string"true". |
龙前,当我们在处理有什么内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
因为引证会议,作家喜欢使用脚本命令,但
例如,如果一个确定的标志是一个集和计数数大于1。
1 2 3 4 5 6 7 8 | FLAG="u p" COUNT=3 if [[ $FLAG && $COUNT -gt '1' ]] ; then echo 'Flag up, count bigger than 1' else echo 'Nope' fi |
这些空间可以得到机会的时候,零长度字符串和变量都是零,所以当你需要和需要与一些shell脚本。
How to declare and use boolean variables in shell script?
与许多其他编程语言不同,bash不按"type"分隔变量。
所以答案很清楚。巴什没有
使用DECLARE语句,我们可以限制变量的值赋值。
1 2 3 4 5 6 7 8 9 | #!/bin/bash declare -ir BOOL=(0 1) #remember BOOL can't be unset till this shell terminate 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" |
"faking a布尔离开A陷阱和未来的读者,为什么不只是使用一个更好的价值比的真实和虚假的?
例如:
1 2 3 4 5 6 7 8 9 10 | build_state=success if something-horrible; then build_state=failed fi if [["$build_state" == success ]]; then echo go home, you are done else echo your head is on fire, run around in circles fi |
POSIX(便携式操作系统接口)
我想这里的关键点是便携性。这就是为什么我的头文件本身就有POSIX。
从本质上讲,所有投票的答案都是正确的,但它们太过具体化了。
基本上,我只想添加更多关于可移植性的信息。
1 | test"${var}" = true && CodeIfTrue || CodeIfFalse |
注意,我不再推荐这个,因为它正在慢慢被否决。
想象一下这些单词
1 | echo $(( true )) |
1 0
1 | echo $(( false )) |
1 1
但使用引号:
1 | echo $(("true" )) |
1
2 bash:"true": syntax error: operand expected (error token is""true"")
sh (dash): sh: 1: arithmetic expression: expecting primary:""true""
同样适用于:
1 | echo $(("false" )) |
shell只能解释字符串。我希望你能理解使用不带引号的关键字有多好。
但在之前的回答中没有人说过。
这是什么意思?嗯,有几件事。
你应该习惯布尔关键字被当作数字来对待,也就是说,
true =0 ,false =1 ,记住所有非零值都被当作false 。因为它们被视为数字,所以您也应该这样对待它们,也就是说,如果定义变量,请说:
1
2var_bool=true
echo"${var_bool}"1true您可以通过以下方式创建它的相反值:
1
2var_bool=$(( 1 - ${var_bool} ))
echo"${var_bool}"11正如您自己看到的,shell第一次使用它时会打印
true 字符串,但从那时起,它都通过分别代表true 或1 的数字0 工作。
最后,你应该如何处理这些信息
首先,一个好习惯是指定
0 代替true ;指定1 代替false 。第二个好习惯是测试变量是否等于零:
1if ["${var_bool}" -eq 0 ]; then YourCodeIfTrue; else YourCodeIfFalse; fi
比尔·帕克被否决了,因为他的定义与普通的代码约定相反。通常,真的定义为0,假的定义为非零。1表示假,9999和-1表示假。与函数返回值相同-0表示成功,任何非零表示失败。对不起,我还没有投票或直接回复他的街头信誉。
Bash建议现在使用双括号代替单括号,MikeHolt给出的链接解释了它们工作方式的不同。7.3。其他比较运算符
一方面,
1 2 3 | #**** NOTE *** This gives error message ***** The_world_is_flat=0; if ["${The_world_is_flat}" -eq true ]; then |
将发出错误语句,应为整数表达式。这适用于任一参数,因为两者都不是整数值。然而,如果我们在它周围加上双括号,它将不会发出错误语句,但会产生错误的值(好吧,在可能的排列中有50%)。它将评估为[[0-eq真]]=成功,也将评估为[[0-eq假]]=成功,这是错误的(hmmm…)。那内置的是一个数值吗?).
1 2 3 | #**** NOTE *** This gives wrong output ***** The_world_is_flat=true; if [["${The_world_is_flat}" -eq true ]]; then |
条件的其他排列也会产生错误的输出。基本上,任何将变量设置为数值并将其与真/假内置进行比较的内容(上面列出的错误条件除外),或将变量设置为真/假内置并将其与数值进行比较的内容。此外,任何将变量设置为真/假内置函数并使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #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所指出的,不要将它们括在引号中)。然后使用单或双等号(=或==)和单或双括号([]或[])。就我个人而言,我喜欢双等号,因为它让我想起了其他编程语言中的逻辑比较,而双引号只是因为我喜欢输入。所以这些工作:
1 2 3 4 5 6 7 8 9 10 11 | #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 |
给你。
在许多编程语言中,布尔类型是或实现为整数的子类型,其中
C中的布尔
python中的布尔值
Java中的布尔
在数学上,布尔代数类似于整数算术模2。因此,如果语言不提供本机布尔类型,最自然和最有效的解决方案是使用整数。这几乎适用于任何语言。例如,在bash中,您可以执行以下操作:
1 2 3 4 | # val=1; ((val)) && echo"true" || echo"false" true # val=0; ((val)) && echo"true" || echo"false" false |
男子狂欢:
((expression))
The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let"expression".
以下是对Miku原始答案的改进,解决了Dennis Williamson对案例的担忧,其中变量没有设置:
1 2 3 4 5 | the_world_is_flat=true if ${the_world_is_flat:-false} ; then echo"Be careful not to fall off!" fi |
并测试变量是否为
1 2 3 | if ! ${the_world_is_flat:-false} ; then echo"Be careful not to fall off!" fi |
对于变量中包含有害内容的其他情况,这是向程序提供的任何外部输入的问题。
在信任任何外部输入之前,必须对其进行验证。但是,当接收到输入时,必须只进行一次验证。
它不必像丹尼斯·威廉姆森建议的那样,通过对变量的每次使用来影响程序的性能。
下面是一个对我有用的简单示例:
1 2 3 4 5 6 7 8 9 | temp1=true temp2=false if ["$temp1" = true ] || ["$temp2" = true ] then echo"Do something." else echo"Do something else." fi |
这里是一个短手
1 2 3 4 5 6 7 | # 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
1 2 3 4 5 6 7 | my_boolean=true _if ${my_boolean} && { echo"True Is True" } || { echo"False Is False" } |
例2
1 2 | my_boolean=false ! _if ${my_boolean} && echo"Not True is True" |
我发现现有的答案令人困惑。
就我个人而言,我只想拥有一些看起来像C的东西。
这段代码在生产中一天工作多次:
1 2 3 4 5 6 | snapshotEvents=true if ($snapshotEvents) then # do stuff if true fi |
为了让大家开心,我测试了:
1 2 3 4 5 6 | snapshotEvents=false if !($snapshotEvents) then # do stuff if false fi |
也很管用。
你不需要括号,我觉得它们很有用。
测试日期:GNUBash,版本4.1.11(2)-发布
Bash初学者指南,Machtlet Garrels,2008年1月11日
我的发现和建议与其他帖子有些不同。我发现我基本上可以像任何"常规"语言那样使用真/假,而不需要"跳铁环"的提示…不需要进行[]或显式字符串比较…我尝试了多个Linux发行版,我测试了bash、dash和busybox。我和她一起跑,没有一声巨响…结果总是一样的。我不知道最初的投票结果最高的帖子是怎么说的。也许时代已经改变了,这就是一切?
如果将变量设置为
请参见下面的示例bash和结果。如果你想确认…
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/sh #not yet defined... echo"when set to ${myBool}" if ${myBool}; then echo"it evaluates to true"; else echo"it evaluates to false"; fi; myBool=true echo"when set to ${myBool}" if ${myBool}; then echo"it evaluates to true"; else echo"it evaluates to false"; fi; myBool=false echo"when set to ${myBool}" if ${myBool}; then echo"it evaluates to true"; else echo"it evaluates to false"; fi; |
产量
1 2 3 4 5 6 | when set to it evaluates to true when set to true it evaluates to true when set to false it evaluates to false |
巴什真的把这个问题和
所有处理彼此的代码空间。我想这主要是历史性的,巴什有时不得不假装成江户。
大多数时候,我可以选择一种方法并坚持下去。在这种情况下,我倾向于声明(最好是在公共库文件中,我可以在实际脚本中包含
1 | TRUE=1; FALSE=0 |
然后我可以使用
1 2 3 4 5 6 7 8 9 10 | testvar=$FALSE if [[ -d ${does_directory_exist} ]] then testvar=$TRUE; fi if (( testvar == TRUE )); then # do stuff because the directory does exist fi |
你必须有纪律。您的
在
我可以用
缺点是有时必须使用
1 | testvar=$TRUE |
不是很漂亮。
这不是一个完美的解决方案,但它涵盖了所有的情况,我需要这样一个测试。