分类: LINUX
2012-07-14 11:03:19
比较字串:[ "string1" = "string2" ] 等价于 [ "string1" == "string2" ]
比较整数:[ "num1" -eq "num2" ] 等价于 (( "num1" == "num2" ))
变量值不为空,且变量值中不包含空格的情况下,变量可不加双引号,当然加了双引号也可以
变量值为空或变量值中包含空格的情况下,变量一定要加双引号
或变量没有申明,比如unset var,引用$var,就一定要加双引号
所以把变量统一加上双引号是个明智的选择
[ <...> -a <...> ] 等价于 [ <...> ] && [ <...> ] 等价于 [[ <...> && <...> ]]
[ <...> -o <...> ] 等价于 [ <...> ] || [ <...> ] 等价于 [[ <...> || <...> ]]
Linux Shell 里面比较字符写法:
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-le 小于等于
-ge 大于等于
-z 空串
= 两个字符相等
!= 两个字符不等
-n 非空串
关于[]中的= == 号两边一定要留空格的原因,用下例来说明:
#[ a=b ] && echo OK
OK
咦,为什么会打印出OK?bash会把a=b理解赋值操作,赋值操作永远为真
#[ a==b ] && OK
OK
同理a==b可以理解为a="=b"赋值操作
我们来看几个实例:
以下几种test语句表达方式
[root@liyao ~]# a=3
[root@liyao ~]# [ "$a" -eq 3 ] echo 1 || echo 0
-bash: [: missing `]' # 这里为什么错了呢?那是因为判断完成之后是要输出结果才能去执行下面的命令的
0
[root@liyao ~]# [ "$a" -eq 3 ] && echo 1 || echo 0
1
[root@liyao ~]#
[root@liyao ~]# (("$a" == 3)) && echo 1 || echo 0
1
[root@liyao ~]#
[root@liyao ~]# [ "$a" -eq "3" ] && echo 1 || echo 0
1
[root@liyao ~]#
[root@liyao ~]# [ "$a" = "3" ] && echo 1 || echo 0
1
[root@liyao ~]#
设置变量为空值
A. Var=’’
[root@liyao ~]# var=''
[root@liyao ~]# echo $var
[root@liyao ~]#
B. abc=""
[root@liyao ~]# abc=""
[root@liyao ~]# echo $abc
[root@liyao ~]#
C. bao=
[root@liyao ~]# echo $bao
[root@liyao ~]#
([ -n "$var" ]
[root@liyao ~]# var=
[root@liyao ~]# [ -n $var ] && echo OK
OK
[root@liyao ~]#
#这个结果错得很明显,为什么呢?[ -n $var ]是先进行了$var变量替换后再进行test测试,变量替换后也就变成了[ -n ],这是个空判断,为真
[root@liyao ~]# [ -n "$var" ] && echo OK
[root@liyao ~]#
# 这样才是正确的结果呀!
注意[ -n "" ]与[ -n " " ]是不一样的,[ -n " " ]为真," "是一个空格,它与空值不一样
[root@liyao ~]# [ -f /etc/services ] && echo 1 || echo 0 测试 /etc/services 是否存在,如果存在则打印 1 不存在打印 0
1
[root@liyao ~]#
[root@liyao ~]# [ -f /etc/ser ] && echo 1 || echo 0
0
[root@liyao ~]# [ ! -f /abc ] && touch /abc
[root@liyao ~]# ll /
total 154
-rw-r--r-- 1 root root 0 Aug 21 23:32 abc
drwxr-xr-x 2 root root 4096 Jul 3 23:09 bin
[root@liyao ~]# [ -d /abc ] && echo 1 || echo 0
0
[root@liyao ~]#
测试 / 下是否有 abc1 这个目录,如果没有则创建该目录
[root@liyao ~]# [ ! -d /abc1 ] && mkdir /abc1
[root@liyao ~]# ls -d /abc1/
/abc1/
[root@liyao ~]#
测试字符串是否为空
测试 $abc 是否为空字符,如果是打印 1 不是则打印 0
[root@liyao ~]# abc="ddd"
[root@liyao ~]# [ -z "$abc" ] && echo 1 || echo 0
0
[root@liyao ~]# ]
测试如果 $abc 为非空字符则打印 1 ,否则打印 0
[root@liyao ~]# [ -n "$abc" ] && echo 1 || echo 0
1
[root@liyao ~]#
两个字符串进行比较
先定义两个变量 liyao 和 oldboy ,然后测试如果 liyao = oldboy 则打印1,否则打印 0
[root@liyao ~]# [ "$liyao" = "$oldboy" ] && echo 1 || echo 0
0
测试如果 liyao 不等于 oldboy 则打印 1 ,否则打印 0
[root@liyao ~]# [ "$liyao" != "$oldboy" ] && echo 1 || echo 0
1
[root@liyao ~]#
[root@liyao ~]# a=1
[root@liyao ~]# b=2
如果 a 等于 b 则输出 1 ,否则输出 0
[root@liyao ~]# [ $a -eq $b ] && echo 1 || echo 0
0
[root@liyao ~]#
如果 a 大于 b 则输出 1 否则输出 0
[root@liyao ~]# [ $a -gt $b ] && echo 1 || echo 0
0
[root@liyao ~]#
如果 a 大于等于 b 则输出 1 否则输出 0
[root@liyao ~]# [ $a -ge $b ] && echo 1 || echo 0
0
[root@liyao ~]#
如果 a 小于 b 则输出 1 否则输出 0
[root@liyao ~]# [ $a -lt $b ] && echo 1 || echo 0
1
[root@liyao ~]#
如果 a 小于等于 b 则输出1 否则输出 0
[root@liyao ~]# [ $a -le $b ] && echo 1 || echo 0
1
[root@liyao ~]#
如果 a 不等于 b 则输出1 否则输出 0
[root@liyao ~]# [ $a -ne $b ] && echo 1 || echo 0
1
[root@liyao ~]#
如果 1 小于 2 则输出 1 否则输出 0
[root@liyao ~]# ((1<2)) && echo 1 || echo 0
1
[root@liyao ~]#
如果1 不等于 2 则输出 1 否则输出 0
[root@liyao ~]# ((1!=2)) && echo 1 || echo 0
1
[root@liyao ~]#
如果 1 等于 2 则输出 1 否则输出 0
[root@liyao ~]# ((1==2)) && echo 1 || echo 0
0
[root@liyao ~]#
如果 a = b 则输出1 否则输出 0
[root@liyao ~]# (($a==$b)) && echo 1 || echo 0
0
[root@liyao ~]#
##########################################################
Test 命令
Test 命令工作原理
test 命令最短的定义可能是评估一个表达式;如果条件为真,则返回一个 0 值。如果表达式不为真,则返回一个大于 0 的值 — 也可以将其称为假值。检查最后所执行命令的状态的最简便方法是使用 $? 值。
test 命令期望在命令行中找到一个参数,当 shell 没有为变量赋值时,则将该变量视为空。这意味着在处理脚本时,一旦脚本寻找的参数不存在,则 test 将报告该错误。
当
试图保护脚本时,您可以通过将所有参数包含在双引号中来解决这个问题。然后 shell 将变量展开,如果变量没有值,那么将传递一个空值给
test。另一种方法是在脚本内增加一个额外检查过程来判断是否设置了命令行参数。如果没有设置命令行参数,那么脚本会告诉用户缺少参数,然后退出。我们
会通过一些例子来更具体地说明所有这些内容。
test 和 [ ]
。
当您使用括号而非 test 时,其后必须始终跟着一个空格、要评估的条件、一个空格和右方括号。右方括号不是任何东西的别名,而是表示所需评估参数的结束。条件两边的空格是必需的,这表示要调用 test,以区别于同样经常使用方括号的字符/模式匹配操作。
#########################################################################
Test 命令的语法:
test expression
test 都评估一个表达式,然后返回真或假。如果它和 if、while 或 until 命令结合使用,则您可以对程序流进行广泛的控制。不过,您无需将 test 命令与任何其它结构一起使用;您可以从命令行直接运行它来检查几乎任何东西的状态。
###########################################################
test 文件运算符
利用这些运算符,您可以在程序中根据对文件类型的评估结果执行不同的操作:
-b file 如果文件为一个块特殊文件,则为真
-c file 如果文件为一个字符特殊文件,则为真
-d file 如果文件为一个目录,则为真
-e file 如果文件存在,则为真
-f file 如果文件为一个普通文件,则为真
-g file 如果设置了文件的 SGID 位,则为真
-G file 如果文件存在且归该组所有,则为真
-k file 如果设置了文件的粘着位,则为真
-O file 如果文件存在并且归该用户所有,则为真
-p file 如果文件为一个命名管道,则为真
-r file 如果文件可读,则为真
-s file 如果文件的长度不为零,则为真
-S file 如果文件为一个套接字特殊文件,则为真
-t fd 如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真
-u file 如果设置了文件的 SUID 位,则为真
-w file 如果文件可写,则为真
-x file 如果文件可执行,则为真
[root@liyao ~]# ll
total 52
-rw------- 1 root root 1012 Jul 3 21:43 anaconda-ks.cfg
-rw-r--r-- 1 root root 27974 Jul 3 21:43 install.log
-rw-r--r-- 1 root root 4708 Jul 3 21:43 install.log.syslog
[root@liyao ~]#
[root@liyao ~]# test -r install.log
[root@liyao ~]# echo $?
0
[root@liyao ~]#
[root@liyao ~]# test -r walter
[root@liyao ~]# echo $?
1
[root@liyao ~]#
由于第一次评估为真 — 文件存在且可读 — 返回值为真,或 0。由于第二次评估的文件不存在,该值为假,返回值不为零。将值指定为零或非零很重要,因为在失败时不会始终返回 1(虽然这是通常返回的值),可能返回一个非零值。
[root@liyao ~]# test "$variable"
[root@liyao ~]# echo $?
1
[root@liyao ~]#
强烈建议进行此种测试时用双引号将变量括住,以让 shell 识别变量(即使变量为空)。默认情况下执行的基本字符串评估和 -n 测试从功能上讲是相同的,如以下示例所示:
vi abc
if test "$1"
then
echo "$1"
fi
所有这些表明,通常不需要 -n,它代表默认操作。
要从一个不同的角度来查看各种可能性,您可以用另一个选项来替换 -n,并检查该值是否为空(相对于非空)。这可以用 -z 选项来实现,代码为:
[root@liyao ~]# bash abc
No values were specified