bash中的复合逻辑测试

bob*_*nto 6 testing bash

关于bash的问题....

我写了一些代码来检查一年是否是一个年级.相关部分如下:

if [ $testnum4 -eq 0 -a $testnum100 -ne 0 ] || [ $testnum400 -eq 0 ]
then
  echo 0
fi
Run Code Online (Sandbox Code Playgroud)

好吧,这段代码确实有效.我的问题是我还不太确定我在做什么.只是为了看看会发生什么,我已经尝试了几种变体:将整个测试表达式包含在方形支持中,使用&&我所拥有的位置-a-o我所拥有的位置||等.除了上面写的一个表达式之外,什么都没有用.我偶然发现它,我很高兴我做到了,但下次我必须做这样的事情,我想知道我在做什么.

那么:任何人都能快速解释复合测试在bash中的运作方式吗?或指向这个主题的好资源的指针?

谢谢.

这是一个失败的代码:

let testnum4=$1%4
let testnum100=$1%100
let testnum400=$1%400

if [ $testnum4 -eq 0 && $testnum100 -ne 0 ] -o [ $testnum400 -eq 0 ]
then
  echo 0
fi
Run Code Online (Sandbox Code Playgroud)

Dav*_* W. 16

感兴趣的小注意事项:方括号实际上是一个Unix命令.查看是否有一个名为/bin/[/usr/bin/[在您的系统上的文件.事实上,试试这个:

$ ls i-il /bin[ /bin/test
571541 -r-xr-xr-x  2 root  wheel  43120 Aug 17  2011 /bin/[
571541 -r-xr-xr-x  2 root  wheel  43120 Aug 17  2011 /bin/test
Run Code Online (Sandbox Code Playgroud)

第一个数字是索引节点号.你看到了,/bin/[并且/bin/test很难相互联系.他们是同一个程序.

稍后我会回到这个意义上......


在BASH和其他Bourne类型的shell中,该if命令仅运行该命令,如果该命令返回退出代码0,则它执行该if子句中的命令.如果该命令未返回退出代码0,则它会跳过if子句中的命令并执行子句中的命令(else如果存在).

因此,这也是有效的:

if sleep 2
then
   echo "That was a good nap!"
fi
Run Code Online (Sandbox Code Playgroud)

您的计算机执行sleep 2命令(如果存在睡眠命令)将返回零退出代码并继续回显这是一个很好的午睡!.

这就是所有的if命令.它运行给定的命令并检查退出代码.


现在,回到[......

您可能希望查看test命令的联机帮助页.您可以看到该test命令似乎具有许多[...]与if语句中相同类型的测试.实际上,在最初的Bourne shell(BASH派生自派生)中,这些是相同的命令结构:

if test -f $my_file
then
    echo "File $my_file exists"
else
    echo "There is no file $my_file"
fi

if [ -f $my_file ]
then
    echo "File $my_file exists"
else
    echo "There is no file $my_file"
fi
Run Code Online (Sandbox Code Playgroud)

实际上,在最初的Bourne shell中,您必须使用test命令而不是方括号.


所以,回到你原来的问题.该-a-o是测试命令(参见参数test手册页例如,你的.if语句可以写成这样:

if test $testnum4 -eq 0 -a $testnum100 -ne 0 || test $testnum400 -eq 0
then
   echo 0
fi
Run Code Online (Sandbox Code Playgroud)

但是,&&并且||不是测试命令参数,因此它们不能在test命令中使用.

请注意,这[是BASH中的内置命令,因此BASH不会/bin/[像原始Bourne shell那样执行.然而,它仍然是一个命令,就像echoBASH中的内置命令一样,尽管它/bin/echo仍然存在.