如何理解bash中的if条件?

如何理解bash中的if条件?,bash,shell,Bash,Shell,我对Bash测试表达式和if测试命令有点困惑: (一) 执行它: # ./test1.sh True # ./test2.sh ./test2.sh: line 5: 90: command not found False # ./test3.sh True (二) 执行它: # ./test1.sh True # ./test2.sh ./test2.sh: line 5: 90: command not found False # ./test3.sh True

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

执行它:

# ./test1.sh
True
# ./test2.sh  
./test2.sh: line 5: 90: command not found  
False
# ./test3.sh
True
(二)

执行它:

# ./test1.sh
True
# ./test2.sh  
./test2.sh: line 5: 90: command not found  
False
# ./test3.sh
True
(三)

执行它:

# ./test1.sh
True
# ./test2.sh  
./test2.sh: line 5: 90: command not found  
False
# ./test3.sh
True
我的问题如下:
a) 对于
test2.sh
,为什么它会抱怨“
未找到命令”


b) 虽然
test1.sh
test3.sh
输出相同的结果,但如果
条件下,它们在
中的含义是否相同?

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

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

if
命令是一个结构,它:

  • 运行命令,然后根据该命令的退出代码
  • 运行其他一些命令
例如,您的系统上有名为
true
false
的程序。因此,您可以创建一个
if
结构,如:

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

现在…当您在bash中执行算术时,您可以使用类似于
$(…)
的结构,它被称为“算术扩展”,因为算术的结果被扩展以替换表达式,就像它是一个变量一样
,如果没有前面的美元符号,则表达式只进行计算,而不是打印

因此..您的第一个
if
命令测试算术展开的计算结果是否为true。大多数有效的算术都应该这样做。您的第二个命令执行展开时就像它是一个命令一样,而不是一个命令。您会收到一个错误,告诉您
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

这两种行为都可能是您想要的,但您没有指出您要解决的问题,因此我不能推荐一种行为。非常感谢您的详细解释!顺便说一句,为什么“
if((2.5+2));然后echo yes;否则echo no;fi
”输出“
no
”,而“
if[$((2.5+2))];then echo yes;else echo no;fi
“not?”@NanXiao:在我的bash(4.3.42)版本中,
((2.5+2))
会导致无效的令牌错误,因为bash算法不支持cecimal点操作。因此,状态代码设置为false,您会得到输出“no”。顺便说一句,我在
zsh
上尝试了它(只是出于好奇),在zsh中,该命令是允许的,状态代码设置为0(true),并打印“是”。@NanXiao-这是一个很好的问题。在第一个示例中,请记住,
$(..)
是一个算术展开。如果它包含的数学无效(因为bash只理解整数),则无法展开任何内容,也无法构造命令行。因此,
if
没有可运行的内容来测试结果,因此没有输出。在第二个示例中,
(…)
是一个语句,而不是展开,因此它可以返回一个
if
可以使用的错误。请注意,
echo$(2.5+2))>/dev/null
不会重定向错误,因为错误不是命令的结果,而是扩展的结果。