bash - 如何理解 bash 中的条件?

标签 bash shell

我对 Bash 测试表达式和 if 测试命令有点困惑:
(1)

#!/bin/bash

count=90

if [ $((count)) ]; then
        echo "True "
else
        echo "False"
fi

执行:

# ./test1.sh
True

(2)

#!/bin/bash

count=90

if $((count)); then
        echo "True "
else
        echo "False"
fi

执行:

# ./test2.sh  
./test2.sh: line 5: 90: command not found  
False

(3)

#!/bin/bash

count=90

if ((count)); then
        echo "True "
else
        echo "False"
fi

执行:

# ./test3.sh
True

我的问题如下:
a) 对于test2.sh,为什么提示“command not found”?
b) 虽然test1.shtest3.sh 输出相同的结果,但是它们在if 条件下的含义相同吗?

最佳答案

任何不产生错误的东西都是有效的。

也就是说,人们在编写 shell 脚本时会遵循一些约定,它们的存在主要是因为它们有意义。

if 命令是一个结构:

  • 运行命令,然后根据该命令的退出代码,
  • 运行一些其他命令。

例如,您的系统上有名为truefalse 的程序。所以你可以制作一个 if 构造如下:

if true; then
  echo TRUE
else
  echo FALSE
fi

当您在 shell 中“将条件括在方括号中”时,您真正正在做的是运行名为 [ 的命令。它可能内置在您的 shell 中,也可能位于 /bin/[,但无论哪种方式,它都是一个命令。它的选项看起来像条件​​,其目的是产生一个退出值,该值将由 if 命令使用。

现在......当你在 bash 中做算术时,你可以使用像 $((...)) 这样的结构,它被称为“Arithmetic Expansion”,因为算术的结果被扩展以替换表达式,就好像它是一个变量一样。当您使用 ((...)) 时,没有前面的美元符号,那么表达式只是被评估,而不是被打印出来。

那么 .. 您的第一个 if 命令会测试算术展开式的计算结果是否为真。大多数有效的算术应该这样做。您的第二个命令执行扩展,就好像它是一个命令,但事实并非如此。您收到错误消息,告诉您 90 不能作为命令运行。第三个命令执行算术运算,但不展开它。与第一个选项一样,只要算法有效,测试就会返回 true。

第一个和第三个变体之间的区别在于,在第一种情况下,test 命令(又名 /bin/[ 或您的 shell 的内置等效命令)正在评估你的算术结果,除非你做了一些愚蠢的事情,比如尝试使用十进制数,否则结果总是正确的,而在第三种情况下,一个有效的算术表达式会导致 0 (零)将显示为“假”。

要在您的 shell 中测试这种差异,请尝试以下操作:

$ if [ $(( 2.5 + 2 )) ]; then echo yes; else echo no; fi    # ERROR
$ if (( 2.5 + 2 )); then echo yes; else echo no; fi         # ERROR, no

$ if [ $(( 2 + 2 )) ]; then echo yes; else echo no; fi      # yes
$ if (( 2 + 2 )); then echo yes; else echo no; fi           # yes

$ if [ $(( 2 - 2 )) ]; then echo yes; else echo no; fi      # yes
$ if (( 2 - 2 )); then echo yes; else echo no; fi           # no

这两种行为都可能是您正在寻找的,但您没有指出您要解决的问题,所以我不能推荐其中一种。

关于bash - 如何理解 bash 中的条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35980922/

相关文章:

mysql - 如何在 bash 中跟踪上次成功运行

bash - 如果任务失败发送电子邮件

linux - O/P重定向到/dev/null时到哪里去了

bash - 错误 : Can't open display: (null) Failed creating new xdo instance on mac OS

python - 如何将一组 csv 文件转换为另一组 csv 文件(具有不同的文件名和格式)?

linux - 修改 tar 存档中嵌套的文件

linux - bash 脚本中的菜鸟

linux - 用于获取 USB 信息的 udev/Bash 脚本

macos - 使用 sed 在 bash 脚本中进行就地重命名

bash - 根据环境自定义 shell 脚本,如开发测试暂存生产