在linux下用shell脚本能够方便地解决很多问题,作为初学者,我也只是窥见了其强大功能中小小的一角。
条件判断,主要包括值的判断和字符串的判断,在shell中还包括对文件的判断。我没有系统的学过shell编程,只是通过一些网上的教程等入了门(当然,是否真的入了门还有待证实),用着用着,我接触到了用于条件判断的 []、[[]],以及 test命令,然后我就困惑了,三者差别在哪里?
在网上荡来荡去,一直找不到令我信服的答案(或许找本教材比较能够解决问题)。最后,在一个类似于谷歌的网站上用英文搜索,终于在stackoverflow上看到了同样的问题,并最终通过网友推荐看到了这个网页,我觉得我的问题应该得到了解答。
[] 和 [[]] 都是用于测试表达式的命令,不过后者较“新”而且更强大,但其兼容性不如前者,只能在Bash、Zsh和KornShell中使用。而 [] 可以在所有的POSIX shell中使用。
几乎在所有的shell(最早的Bourne Shells除外)中,[] 和 test 命令是等同的。
[[]] 可以看做是[] 的扩展,其使用更为灵活,而且能够支持更多的操作。现将一些使用上的差别总结如下:
< 和 > :在 [] 中使用 < 或者 > ,必须使用转义字符,否则会被解释为重定向符号,而在 [[]] 中,可以直接使用。
逻辑 与 和 或 :在 [[]] 中可以直接使用 && 和 || ,而在 [] 内部是不能直接使用这两个逻辑符号的,当然,在 [] 内部可以通过 -a 或者 -o 来判断逻辑关系,但是这两个操作符已经被弃用了(目前还是可以使用的),&& 和 ||只能在 [] 之间使用,如
[ "\$a" = a ] && [ "\$b" = b ]
关于变量空格的问题:如果变量本身包含空格,在 [] 中必须通过引号引起来才能作为一个整体,而在 [[]] 中,则可以直接使用
在比较字符串时, [[]] 中可以使用==,而 [] 中不能使用==
[[]] 中可以使用正则表达式, [] 中不能使用正则表达式
何时使用 [] ,何时使用 [[]] 呢?经验说,如果不需要考虑代码的可移植性,那么 [[]] 是一个不错的选择,因为它的使用更加灵活,使用过程中也不容易出错。可是如果可移植性是一个不得不考虑的问题,那还是老老实实用 [] 吧。如果是测试整数表达式,或许,你还可以试试使用算术表达式。
最后,来看看条件表达式都有哪些吧!(以下内容摘自test命令的手册)
1、整数判断 | ||||
int1 -eq int2 | int1 is equal to int2 | |||
int1 -ge int2 | int1 is greater than or equal to int2 | |||
int1 -gt int2 | int1 is greater than int2 | |||
int1 -le int2 | int1 is less than or equal to int2 | |||
int1 -lt int2 | int1 is less than int2 | |||
int1 -ne int2 | int1 is not equal to int2 | |||
2、字符串判断 | ||||
-n str | the length of str is nonzero | |||
-z str | the length of str is zero | |||
str1 = str2 | the strings a equal | |||
str1 != str2 | the strings are not equal | |||
3、文件判断 | ||||
file1 -ef file2 | file1 and file2 have the same device and inode numbers | |||
file1 -nt file2 | file1 is newer than file2 | |||
file1 -ot file2 | file1 is older than file2 | |||
-b file | file exists and is block special | |||
-c file | file exists and is character special | |||
-d file | file exists and is a directory | |||
-e file | file exists | |||
-f file | file exists and is a regular file | |||
-h file | file exists and is a symbolic link (same as -L) | |||
-L file | file exists and is a symbolic link (same as -h) | |||
-p file | file exists and is a named pipe | |||
-r file | file exists and read permission is granted | |||
-s file | file exists and has a size greater than zero | |||
-S file | file exists and is a socket | |||
-t fd | file descriptor fd is opened on a terminal | |||
-w file | file exists and write permission is granted | |||
-x file | file exists and execute (or search) permission is granted | |||
4、逻辑判断 | ||||
expression | expression is true | |||
! expression | expression is false | |||
expr1 -a expr2 | both expression1 and expression2 are true | |||
expr1 -o expr2 | either expression1 or expression2 is true |