如何在Shell脚本中声明和使用布尔变量?

我尝试使用以下语法在Shell脚本中声明布尔变量:


variable=$false


variable=$true

这个对吗?另外,如果我想更新该变量,我会使用相同的语法吗?最后,使用布尔变量作为表达式的以下语法正确吗?


if [ $variable ]


芜湖不芜
浏览 2778回答 3
3回答

达令说

bool=trueif [ "$bool" = true ]有三苦的(问题原)答案我不推荐接受的答案1。它的语法很漂亮,但是有一些缺陷。说我们有以下情况。if $var; then&nbsp; echo 'Muahahaha!'fi在以下情况2中,此条件将评估为true并执行嵌套命令。# Variable var not defined beforehand. Case 1var=''&nbsp; # Equivalent to var="".&nbsp; &nbsp; &nbsp; &nbsp; Case 2var=&nbsp; &nbsp; #&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Case 3unset var&nbsp; #&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Case 4var='<some valid command>'&nbsp; #&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Case 5通常,仅在您的“布尔”变量(var在此示例中)显式设置为true 时,才希望条件评估为true。所有其他情况都是危险的误导!最后一种情况(#5)特别顽皮,因为它将执行变量中包含的命令(这就是为什么条件对于有效命令3、4评估为true的原因)。这是一个无害的示例:var='echo this text will be displayed when the condition is evaluated'if $var; then&nbsp; echo 'Muahahaha!'fi# Outputs:# this text will be displayed when the condition is evaluated# Muahahaha!引用变量更安全,例如if "$var"; then。在上述情况下,您应该得到一条警告,提示找不到该命令。但是我们仍然可以做得更好(请参阅底部的建议)。另请参阅Mike Holt对Miku原始答案的解释。Hbar的答案有问题这种方法也具有意外的行为。var=falseif [ $var ]; then&nbsp; echo "This won't print, var is false!"fi# Outputs:# This won't print, var is false!您可能希望上述条件的计算结果为false,从而从不执行嵌套语句。惊喜!引用值("false"),引用变量("$var")或使用test或[[代替[都没有区别。我的建议:我建议您通过以下方法检查“布尔值”。他们按预期工作。bool=trueif [ "$bool" = true ]; thenif [ "$bool" = "true" ]; thenif [[ "$bool" = true ]]; thenif [[ "$bool" = "true" ]]; thenif [[ "$bool" == true ]]; thenif [[ "$bool" == "true" ]]; thenif test "$bool" = true; thenif test "$bool" = "true"; then它们几乎相等。您将需要比其他答案5中的方法键入更多的击键,但是您的代码将更具防御性。脚注此后,Miku的答案已被编辑,不再包含(已知)缺陷。并非详尽的清单。在此上下文中,有效命令表示存在的命令。命令的使用正确与否无关紧要。例如man woman,即使不存在这样的手册页,它也仍然被视为有效命令。对于无效(不存在)的命令,Bash只会抱怨找不到该命令。如果您在意长度,则第一个建议是最短的。

富国沪深

关于Bash内置函数true,尤其是Bash如何扩展和解释方括号内的表达式,这里似乎存在一些误解。miku的答案中的代码与内置的Bash true,nor /bin/true或true命令的任何其他形式完全无关。在这种情况下,true是不是一个简单的字符串罢了,以及无呼叫true命令/内置是有史以来,既不是变量赋值,也不由条件表达式的评价。以下代码在功能上与miku答案中的代码相同:the_world_is_flat=yeahif [ "$the_world_is_flat" = yeah ]; then&nbsp; &nbsp; echo 'Be careful not to fall off!'fi的唯一这里不同的是,四个字符被比较是“Y”,“E”,“A”,并且代替“T”“H”,“R”,“U”,和“e”的。而已。yeah在Bash解析令牌时,没有尝试调用名为named的命令或内置命令,也没有进行任何形式的特殊处理(在miku的示例中)true。它只是一个字符串,并且完全是任意的。更新(2014-02-19):跟随miku的答案中的链接之后,现在我看到了一些混乱的来源。Miku的答案使用单括号,但他链接到的代码段不使用括号。只是:the_world_is_flat=trueif $the_world_is_flat; then&nbsp; echo 'Be careful not to fall off!'fi这两个代码段的行为方式相同,但是括号完全改变了引擎盖下发生的事情。这是Bash在每种情况下所做的事情:没有括号:将变量$the_world_is_flat扩展为字符串"true"。尝试将字符串解析"true"为命令。查找并运行true命令(内置命令或/bin/true,具体取决于Bash版本)。将true命令的退出代码(始终为0)与0进行比较。回想一下,在大多数shell中,退出代码0表示成功,而其他任何代码则表示失败。由于退出代码为0(成功),因此执行if语句的then子句括号:将变量$the_world_is_flat扩展为字符串"true"。解析现在已经扩展的条件表达式,其形式为string1 = string2。该=运算符是bash的字符串比较运算符。所以...在"true"和上进行字符串比较"true"。是的,两个字符串相同,因此条件的值是true。执行if语句的then子句。无括号代码有效,因为该true命令返回的退出代码为0,表示成功。括号内的代码有效,因为的值$the_world_is_flat与true右侧的字符串文字相同=。只是为了说明问题,请考虑以下两个代码段:此代码(如果以root特权运行)将重新引导计算机:var=rebootif $var; then&nbsp; echo 'Muahahaha! You are going down!'fi此代码仅显示“ Nice try”。重新启动命令不被调用。var=rebootif [ $var ]; then&nbsp; echo 'Nice try.'fi更新(2014年4月14日)要回答在评论有关之间的差异问题=和==:据我所知,没有任何区别。该==运营商特定的Bash-代名词=,而据我所看到的,他们的工作完全一样在所有上下文中。但是请注意,我是专门讨论在或测试中使用的=和==字符串比较运算符。我不建议这样做,并且在bash中到处都是可以互换的。[ ][[ ]]===例如,您显然不能使用进行变量赋值==,例如var=="foo"(从技术上讲,您可以这样做,但是varwill 的值是"=foo",因为Bash ==在这里没有看到运算符,而是看到了=(赋值)运算符,然后是文字值="foo",变成"=foo")。另外,尽管=和==可以互换,但是您应该记住,这些测试的工作方式确实取决于您是在[ ]还是内部使用它[[ ]],还取决于是否引用了操作数。你可以阅读更多关于高级Bash脚本编程指南:7.3其他比较操作符(向下滚动到的讨论=和==)。
打开App,查看更多内容
随时随地看视频慕课网APP