shell学习十七--条件表达式test、[]、[[]]

一、条件测试
测试语句
在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作,
有时也会通过与if等条件语句相结合,让我们可以方便的完成判断。
格式1:test <测试表达式>
格式2:[<条件表达式>]
格式3:[[<条件表达式>]]

说明:
格式1和格式2是等价的。
格式3为扩展的test命令,有网友推荐用格式3。

提示

1、测试文件是否存在
[root@node01 ~]# test -f file&& echo 1||echo 0
0
[root@node01 ~]# touch file
[root@node01 ~]# test -f file&& echo 1||echo 0
1

[root@node01 ~]# test ! -f file&& echo 1||echo 0 取反
0

字符串判断
[root@node01 ~]# arg=
[root@node01 ~]# test -n "$arg" &&echo 1||echo 0
0
[root@node01 ~]# test ! -n "$arg" &&echo 1||echo 0
1
[root@node01 ~]# test -z "$arg" &&echo 1||echo 0    
1
[root@node01 ~]# test -z "$arg" &&echo true||echo false 
true

2、中括号
[root@node01 ~]# [ -f file ]&& echo 1||echo 0
1
[root@node01 ~]# rm file
[root@node01 ~]# [ -f file ]&& echo 1||echo 0
0
[root@node01 ~]# [ ! -f file ]&& echo 1||echo 0 
1

可以简写(不存在就不理他)
[root@node01 ~]# [ -f file ]||echo 0  

[root@node01 ~]# [ -f file ]&& echo 1  
1

双中括号
[root@node01 day6]# [[ -f file ]]&& echo 1||echo 0
0
[root@node01 day6]# [[ -f file ]]&& echo 1||echo 0
1
[root@node01 day6]# [[ -f file && -d dir ]]&& echo 1||echo 0   
0
[root@node01 day6]# [[ -f file || -d dir ]]&& echo 1||echo 0  
1
[root@node01 day6]# mkdir dir
[root@node01 day6]# [[ -f file || -d dir ]]&& echo 1||echo 0
1

二、总结
以上3种格式参数用法一样,只是语法会有区别,逻辑符等。
文件测试操作符
   -e     该“文件”是否存在(常用)(exist)
   -f     该“文件”是否为文件(file) (常用)
   -s     文件的大小是否为0
   -d     该“文件”是否为目录(directory)
   -b     该“文件”是否为一个快设备(block)
   -c     该“文件”是否为一个字符设备(char)
   -S     该“文件”是否为一个套接字文件(socket)
   -P     该“文件”是否为一个FIFO(管道)文件(pipe)
   -L     该“文件”是否为一个连接文件。(link)
文件的“权限”检测,如 test  -r   filename
    -r    检测该文件是否具有“可读”属性
    -w    检测该文件是否具有“可写”属性
    -x    检测该文件是否具有“可执行”属性
    -u    检测该文件是否具有“SUID”属性
    -g    检测该文件是否具有“SGID”属性
    -k    检测该文件是否具有“Sticky bit”属性
    -s    检测该文件是否为“非空白文件”
比较两个文件,如: test file1 -nt file2
    -nt   判断file1是否比file2新(newer than)
    -ot   判断file1是否比file2旧(older than)
    -ef   判断file1与file2是否为同一个文件,可用于判断硬链接。主要判断两个文件是否均指向通过一个inode。(equal file)

更多用法请查看帮助(man test)

1、实例(针对于文件)
[root@node01 day6]# mkdir wolf
[root@node01 day6]# [ -f wolf ]&& echo 1||echo 0    
1
[root@node01 day6]# mkdir wolf1
[root@node01 day6]# [ -f wolf1 ]&& echo 1||echo 0
0
[root@node01 day6]# [ -e wolf1 ]&& echo 1||echo 0 
1
[root@node01 day6]# [ -d wolf1 ]&& echo 1||echo 0 
1
[root@node01 day6]# [ -d wolf ]&& echo 1||echo 0 

r权限root也有读权限,切换到普通用户测试
[wolf@node01 day6]$  [[ -r wolf ]]&& echo 1||echo 0        
0
[wolf@node01 day6]$  [[ -r wolf ]]&& echo 1||echo 0 
1
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -r wolf ]&& echo 1||echo 0   
1
[wolf@node01 day6]$  [ -x wolf ]&& echo 1||echo 0  
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0  
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -x wolf ]&& echo 1||echo 0  
1
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
0
[wolf@node01 day6]$  [ -w wolf ]&& echo 1||echo 0 
1
0

2、字符串测试
    字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为0,字符串
是否为NULL(注:bash区分零长度字符串和空字符串)。
    “=”比较两个字符串是否相同,与==等价,如if[ "$a" = "$b"  ],其中$a这样的变量
最好用“”括起来,因为如果中间有空格,*等符号就可能出错,当然更好的方法就是
[ "${a}" = "${b}" ]。“!=” 比较两个字符串是否相同,不同则为“是”。

字符串比较符有如下4种(下面的字符串测试操作符号务必用""引起来):
  =  测试两个字符串是否相等
 !=  测试两个字符串是否不相等
 -z  测试字符串是空字符串
 -n  测试字符串是非空字符串
提示:
a、-n比较字符串长度是否不为0,如果不为0则为真,如[ -n "$wolf" ]
b、-z比较字符串长度是否等于0,如果等于0则为真,如[ -z "$wolf" ]
c、字符串比较符号两端最好有空格。多参考系统脚本。
d、字符串或者字符串变量比较都加双引号比较。

例子
[root@node01 day6]# [[ -n "abc" ]]&& echo 1||echo 0     
1
[root@node01 day6]# [ -n "" ]&& echo 1||echo 0     
0
[root@node01 day6]# laolang="wolf"
[root@node01 day6]# [ -n "$laolang" ]&& echo 1||echo 0 
1
[root@node01 day6]# laolang=""
[root@node01 day6]# [ -n $laolang ]&& echo 1||echo 0     (这里不加双引号就有问题)
1
[root@node01 day6]# [ -n "$laolang" ]&& echo 1||echo 0
0
 
[root@node01 day6]# [ -z "$laolang" ]&& echo 1||echo 0 
1
[root@node01 day6]# laolang="abc"
[root@node01 day6]# [ -z "$laolang" ]&& echo 1||echo 0
0

[root@node01 day6]# [ "abc" = "abd" ]&& echo 1||echo 0            
0
[root@node01 day6]# [ "abc" = "abc" ]&& echo 1||echo 0 
1
[root@node01 day6]# [ "abc" != "abc" ]&& echo 1||echo 0
0
[root@node01 day6]# [ "abc" != "abd" ]&& echo 1||echo 0 
1
[root@node01 day6]# test=""
[root@node01 day6]# [ "$test" != "abd" ]&& echo 1||echo 0   
1
[root@node01 day6]# test="abd" 
[root@node01 day6]# [ "$test" != "abd" ]&& echo 1||echo 0
0

3、整数比较
在[]中使用的比较符,两个整数之间的判断,例如test n1 -eq n2
    -eq        判断两数值相等(equal)
    -ne        判断两数值不等(not equal)
    -gt        判断n1大于n2(greater than)
    -lt        判断n1小于n2(less than)
    -ge        判断n1大于等于n2(greater than or equal)
    -le        判断n1小于等于n2(less than or equal)
在(())和[[]]中使用的比较符
    ==或者=    判断两数值相等(equal)
    !=         判断两数值不等(not equal)
    >          判断n1大于n2(greater than)
    >=         判断n1小于n2(less than)
    <          判断n1大于等于n2(greater than or equal)
    <=         判断n1小于等于n2(less than or equal)
注意:
a、=和!=在[]中使用不需要转义,包含“<”和“>”的符号在[]中使用需要转义,对于数字
不转义的结果未必会报错,但是结果可能会不对。
b、"<"符号的意思是小于,if[[ "$a" < "$b" ]],if[ "$a" < "$b" ].在[]中需要转义,
因为shell也用<和>重定向。
c、">"符号的意思是大于,if[[ "$a" > "$b" ]],if[ "$a" > "$b" ].在[]中需要转义,
因为shell也用<和>重定向。
d、比较最好用==

例子
[root@node01 day6]# [ 12 -eq 13 ]&&echo 1||echo 0
0
[root@node01 day6]# [ 12 -gt 13 ]&&echo 1||echo 0  
0
[root@node01 day6]# [ 12 -lt 13 ]&&echo 1||echo 0  
1
[root@node01 day6]# [ 12 < 13 ]&&echo 1||echo 0   
-bash: 13: No such file or directory
0
[root@node01 day6]# [ 12 \< 13 ]&&echo 1||echo 0
1
[root@node01 day6]# [ 12 \> 13 ]&&echo 1||echo 0 
0
[root@node01 day6]# [[ 12 > 13 ]]&&echo 1||echo 0 
0
[root@node01 day6]# [[ 12 < 13 ]]&&echo 1||echo 0 
1
[root@node01 day6]# [[ 12 = 13 ]]&&echo 1||echo 0 
0
[root@node01 day6]# [[ 12 = 12 ]]&&echo 1||echo 0 
1
[root@node01 day6]# (( 12 = 12 ))&&echo 1||echo 0            比较最好用==
-bash: ((: 12 = 12 : attempted assignment to non-variable (error token is "= 12 ")
0
You have new mail in /var/spool/mail/root
[root@node01 day6]# (( 12 == 12 ))&&echo 1||echo 0
1

4、逻辑操作符
多重条件判断
在[]中使用逻辑操作符
  -a    (and)两个条件同时成立。例如: test -r file -a -x file  若文件file具有可读和可执行权限,则为真。
  -o    (or)两个条件任何一个成立。例如: test -r file -o -x file  则file具有r或x权限时,就可以回传true
   !    条件求反,如test ! -x file,当file 不具有x时,回传true
 在[[]]中使用逻辑操作符
  &&    and与,两端都为真
  ||    or或,两端有一个为真
  !     not非,相反则为真
 结论:-a&&的运算规则:只有两端都是1才是真
 真1 假0
 and 1*0=0 假
 and 0*1=0 假
 and 1*1=1 真
 and 0*0=0 假
 只有两端都是1才为真
 
 结论:-o|| 两端都是0才为假,任何一端不为0都是真。
 or 1+0=0 真
 or 0+1=0 真
 or 1+1=1 真
 or 0+0=0 假 
 两端都是0才为假,不为0就是真。
例子:
[root@node01 day6]# ll /etc/rc.local 
lrwxrwxrwx. 1 root root 13 Jul  7 07:37 /etc/rc.local -> rc.d/rc.local
You have new mail in /var/spool/mail/root
[root@node01 day6]# ll /etc/services 
-rw-r--r--. 1 root root 641020 Oct  2  2013 /etc/services
[root@node01 day6]# f1=/etc/rc.local;f2=/etc/services 
[root@node01 day6]# [ -f "$f1" && -f "$f2" ]&& echo 1||echo 0
-bash: [: missing `]'
0
[root@node01 day6]# [ -f "$f1" -a -f "$f2" ]&& echo 1||echo 0  
1
[root@node01 day6]# [[ -f "$f1" && -f "$f2" ]]&& echo 1||echo 0
1

[root@node01 day6]# [ -n "$f1" -a -z "$f2" ]&& echo 1||echo 0    
0
[root@node01 day6]# [ -n "$f1" -o "$f2" ]&& echo 1||echo 0    
1
[root@node01 day6]# [ -n "$f1" -o "$f2" = "$f1" ]&& echo 1||echo 0
1
[root@node01 day6]# [ -n "$f1" -a "$f2" = "$f1" ]&& echo 1||echo 0 
0
[root@node01 day6]# echo ${#f1}
13
[root@node01 day6]# echo ${#f2}
13
[root@node01 day6]# [ -n "$f1" -a "${#f2}" = "${#f1}" ]&& echo 1||echo 0
1
[root@node01 day6]# 

[root@node01 day6]# n1=12;n2=13
[root@node01 day6]# [[ $n1 -eq $n2 && -z "$1" ]]&& echo 1||echo 0   
0
[root@node01 day6]# [[ ! $n1 -eq $n2 && ! -z "$n1" ]]&& echo 1||echo 0
1

学习可以多看系统脚本/etc/init.d/
 

test条件表达式
[root@node01 day6]# test -f $f1&&echo 1||echo 0
1
[root@node01 day6]# test -f $f1&&echo 1||echo 0
1
[root@node01 day6]# test -n "$f1"&&echo 1||echo 0 
1
[root@node01 day6]# test -z "$f1"&&echo 1||echo 0 
1
[root@node01 day6]# test $n1 -eq $n2&&echo 1||echo 0 
0
[root@node01 day6]# test $n1 -eq $n2 -a -z "$2" &&echo 1||echo 0 
0
[root@node01 day6]# test a -ot b &&echo 1||echo 0
1
[root@node01 day6]# test a -nt b &&echo 1||echo 0 
0
连接文件
[root@node01 day6]# test a -ef b &&echo 1||echo 0  
0
[root@node01 day6]# ln a c
[root@node01 day6]# test a -ef c &&echo 1||echo 0 
1
 

你可能感兴趣的:(shell)