<>

3.3. (( and [[

虽然test命令功能非常强大,但有些时候也非常笨拙,像需要转义时候或者是需要区别字符串比较和算术比较。所幸的是,Bash环境还包含了另外两种测试方式,这两种方式对于那些熟悉 C、C++、或者是 Java® 语法的朋友会更自然一些。

复合命令 (( )) 计算一个算术表达式的值,并且当运算结果为0时,设置返回的状态为1,运算结果为非0的值时则设置返回状态为0。同时你也不必转义(())之间的操作符号。支持整数的四则运算。被0除会导致错误,但是不会溢出。你也可以在其中运行 usual C 形式的算术表达式、逻辑和移位操作。let 命令也可以运行一个或多个算术表达式。它常常用来给算术变量赋值。

Example 3.5. 赋值并测试算术表达式

[user@domain ~]$ let x=2 y=2**3 z=y*3; echo $? $x $y $z
0 2 8 24
[user@domain ~]$ (( w=(y/x) + ( (~ ++x) & 0x0f ) )); echo $? $x $y $w
0 3 8 16
[user@domain ~]$ (( w=(y/x) + ( (~ ++x) & 0x0f ) )); echo $? $x $y $w
0 4 8 13

(( ))一样复合命令[[ ]]允许你使用更自然的语法对文件或字符串进行测试。你也可以通过括号和逻辑操作符连接多个测试。

Example 3.6. 使用复合命令 [[

[user@domain ~]$ [[ ( -d "$HOME" ) && ( -w "$HOME" ) ]] &&  
>  echo "home is a writable directory"
home is a writable directory

当使用=!=[[复合命令也可以对字符串执行模式匹配,针对通配符的匹配如Example 3.7, “通过 [[ 做匹配 tests”所示。

Example 3.7. 通过 [[ 做匹配 tests

[user@domain ~]$ [[ "abc def .d,x--" == a[abc]*\ ?d* ]]; echo $?
0
[user@domain ~]$ [[ "abc def c" == a[abc]*\ ?d* ]]; echo $?
1
[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* ]]; echo $?
1

你甚至也可以通过[[执行算术操作,但是请谨慎,只有是在((复合命令中,<>操作符会把字符串作为操作对象测试其对应的次序前后。Example 3.8, “通过 [[ 做算术测试”中通过几个例子做了演示。

Example 3.8. 通过 [[ 做算术测试

[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* || (( 3 > 2 )) ]]; echo $?
0
[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* || 3 -gt 2 ]]; echo $?
0
[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* || 3 > 2 ]]; echo $?
0
[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* || a > 2 ]]; echo $?
0
[user@domain ~]$ [[ "abc def d,x" == a[abc]*\ ?d* || a -gt 2 ]]; echo $?
-<application>Bash</application>: a: unbound variable