shell中的条件测试_第1张图片

1.测试内容 

2.测试方法 

3.命令执行 

  在shell脚本中应用条件测试时,关键是“测试表达式”。在条件语句中测试时首先分清楚测试什么类型的信息:数字、字符串、还是一个文件,要么就是一个逻辑关系。当遇到不同的测试类型时自然就有不同的“测试属性”,理解这个测试属性是必须的。不然就不知道从何处下手。

  判断的返回值:真、假。

  当判断的条件是一个命令时,始终认为是返回为真;缺省表达式,返回为假。

命令 用法
test test EXPRESSION
[ [ EXPRESSION ]

例子:缺省表达式,默认为“假”

[view@payqa2 ~]$ [ ] && echo "true"
[view@payqa2 ~]$ [ ! ] && echo "true"
true


1.测试内容


  表达式的“测试属性”分类

    1.1.字符串测试

    1.2.数字比较

    1.3.文件测试

    1.4.逻辑判断


1.1.字符串测试(判断字符串相等、为空、不为空)

  使用时,与表达式左右要有一个空格分开。

表达式用法

test [
test $lastuser [ $loguser ]          ①
为空
test $lastuser == $loguser
[ $loguser == "sunny" ]   
相等
test -n lastuser [ -n $lastuser ]       非空
test -z loguser [ -z $loguser ]       为空
比较时“==”两边保留空格,赋值时取消空格。


① 测试为空、不为空时,条件判断执行的语句

$ cat string_is_null.sh
#!/bin/bash
#
if [ $1 ]
then
        echo 'Execute then. true'
else
        echo 'Execute else. false'
fi

  为空时,执行了else语句;不为空,执行了then语句。

$ ./string_is_null.sh
Execute else. false
$ ./string_is_null.sh  hello
Execute then. true


② “-n”如何影响if选择语句

$ cat string_n.sh
#!/bin/bash
#
judge(){
        if [ -n $1 ]
        then
                echo 'Execute then. true'
        else
                echo 'Execute else. false'
        fi
}
K="hello"
S=""

echo -ne 'K="hello",\t[ -n $K]\t'
judge $K
echo -ne 'S="",\t\t[ -n $S]\t'
judge $S
$ ./string_n.sh
K="hello",      [ -n $K]        Execute then. true
S="",           [ -n $S]        Execute then. true

  测试结果,令人吃惊!


③ 把上边“-n”替换成“-z”

$ ./string_z.sh
K="hello",[ -z $K]    Execute else. false
S="",[ -z $S]         Execute then. true

  为空时,执行了then语句;不为空,执行了else语句。


④ 测试位置变量的有无

存在位置变量的时候,不提示;不存在位置变量时,提示未知变量为空。

# cat test.sh
#!/bin/bash
#
if [ -z $1 ];then
        echo '$1 is null.'
fi
# ./test.sh 7
# ./test.sh hello
# ./test.sh
$1 is null.

也可以通过这个小程序来测试脚本里使用了某个环境变量(ZCW_TS)是否存在。


⑤比较时竟然可以用“=”

  阅读tomcat脚本时发现的(setclasspath.sh)

[root@iZm5e7mrdpxqswsmtrugo6Z tmp]# cat haha.sh 
#!/bin/bash

if [ "x${hh}" = "x" ]; then
    echo "My god, = is ok."
else
    echo "he he."
fi
[root@iZm5e7mrdpxqswsmtrugo6Z tmp]# ./haha.sh 
My god, = is ok.


1.2.数字比较(整数比较大小、等于)

表达式用法

expr test [ 说明

$age1 -eq $age2

$age1 -ne $age2

test $age1 -eq $age2

test $age1 -ne $age2

[ $age1 -eq $age2 ]

[ $age1 -ne $age2 ]

等于

不等于

$age1 -gt $age2

$age1 -lt $age2

test $age1 -gt $age1

test $age2 -lt $age2

[ $age1 -gt $age1 ]

[ $age2 -lt $age2 ]

大于

小于

$age1 -ge $age1

$age2 -le $age2

test $age1 -ge $age1

test $age2 -le $age2

[ $age1 -ge $age1 ]

[ $age2 -le $age2 ]

大等于

小等于


*举例说明

$int1 -eq $int2: # 数字相等
$int1 -ge $int2: # int1 ≥ int2
$int1 -gt $int2: # 〉
$int1 -le $int2: # ≤
$int1 -lt $int2: # 〈
$int1 -ne $int2: # ≠


  例子:当k的值大于3时,循环结束。

#!/bin/bash
declare -i k=0

while true; do
    if [ $k -gt 3 ]; then
        exit;
    else
        let k+=1
    fi
    echo $k
done


1.3.文件测试

表达式用法

test [ 说明
-b /dev/cdrom [ -b /dev/cdrom ] 存在且为块文件
-c /etc/inittab
[ -c /etc/fstab ] 存在……字符文件
-d /data01
…… ……且为目录文件
-e /~/.ssh/keys
…… ……存在
-s /~/.ssh/keys …… 是否非空
-f /etc/http/conf.d/ssl.cf
…… 存在且为常规文件
-w /data01/tmp/http.log
…… ……可写
-L /data01/tmp/http.log
…… ……符号链接
-u /data01/tmp/http.log
…… 设置suid位
-r /data01/tmp/http.log …… 存在且可读
-x /dinglicom/bin/httpd
…… ……可执行


*说明

file1 -nt file2:文件 file1 更新一些

file1 -ot file2:旧


-d filefile文件存在,并且是一个目录

-e file文件存在

-h file文件存在,并且是一个符号链接

-L file:“同上”

-r file文件存在,并且被赋予了“读”权限

-w file文件存在,并且被赋予了“写”权限

-x file:文件存在,并且被赋予了“执行”(“进入目录”)权限

-s file文件存在,并且大小大于零

-S file文件存在,并且是一个套接字文件


[web@h p]$ test -x dir_perm_test/
[web@h p]$ echo $?
1
[web@h p]$ ll dir_perm_test/
total 20
drw------- 2 web web 4096 Apr  8 01:44 dir_perm_test
[web@h p]$ ll dir_perm_test/
ls: cannot access dir_perm_test/file1: Permission denied
ls: cannot access dir_perm_test/file4: Permission denied
ls: cannot access dir_perm_test/file2: Permission denied
ls: cannot access dir_perm_test/file3: Permission denied
total 0
-????????? ? ? ? ?            ? file1
-????????? ? ? ? ?            ? file2
-????????? ? ? ? ?            ? file3
-????????? ? ? ? ?            ? file4
[web@h p]$ cd dir_perm_test/
-bash: cd: dir_perm_test/: Permission denied
[web@h p]$ chmod u+x dir_perm_test/;cd dir_perm_test/
[web@h p]$ touch file5
[web@h p]$ test -s file5
[web@h p]$ echo $?
1


1.4.逻辑判断组合

  “逻辑判断组合”就像胶水一样把上边“3类”逻辑判断结合起来。


表达式用法

符号
含义
!
-a
-o


  逻辑判断在脚本中的应用:

  •  错误示范(组合字符串判断):

#!/bin/bash
#
clear
#
DISPLAY="Usage show.\n
d/D show disks usages.\n
m/M show memory usages.\n
s/S show swap usages.\n

By the way, if you want exit this script, input 'quit' or 'q'.
"
CHOICE=""
#
echo -e $DISPLAY
read -p "Your choice: " CHOICE
#
#while [ $CHOICE != "quit" ]
while [ $CHOICE != "quit" -o $CHOICE != "q" ]
do
    # test
    #echo $CHOICE
    # while 1
    case $CHOICE in
    d|D)
        echo "Disk info:"
        df -Ph
        ;;
    m|M)
        echo "Memory info:"
        free -m | grep -v "swap"
        ;;
    s|S)
        echo "Swap info:"
        free -m | grep -i "swap"
        ;;
    *)
        echo -e "\tUnkown optios."
        sleep 1
        echo -e $DISPLAY
    esac
    
    # while 2
    read -p "Once more. Your choice: " CHOICE
    # test
    #echo $CHOICE

done

  脚本执行后无法退出,错误就出在逻辑判断上。


  •  正确示范:

while [ $CHOICE != "quit" -a $CHOICE != "q" ]

  条件判断由于使用了逻辑组合“-o”、“-a”,分别需要对于前后两个逻辑判断计算结果。需要退出时,必须判断为假。当使用了组合时,会综合判断。

  因为,“或”在满足后边逻辑判断为“假”需要退出时,前边判断为真,后边判断失效,整体结果为真,程序继续执行;反之,前边逻辑判断满足退出条件时,为假,会继续执行后边逻辑判断为“真”的条件测试(前边为假的“或”运算,后边判断不失效),整体结果依然为真;于是,循环体无法退出。

  当选择“与”时,任意一个退出满足条件满足了即退出循环体。若前边判断为“假”,后边失效,整体结果为“假”,循环终止;当前边为“真”时,后边判断继续,进行为“假”的判断,整体结果为假


*说明

缺省表达式,返回为假。


[web@h p]$ test
[web@h p]$ echo $?
1
[web@h p]$ test da
[web@h p]$ echo $?
0
[ -d $LOCALDIRECTORY ] && $RM -fr $LOCALDIRECTORY
[ ! -d $LOCALDIRECTORY ] && $MKDIR -pv $LOCALDIRECTORY



--------------------------

  小括号($(cat /etc/inittab))用来运行命令中括号([ i -eq j ])用来做条件判断大括号(${user}1)用来界变量定字符串长度。两个小括号套用,在 for循环 里使用、或者 数字运算

--------------------------


2.测试方法


  测试文件属性、测试字符串、数字比较。

用法
说明
-a file
文件存在为真
-b file
是块文件为真
-c file
是字符文件为真
-d file
是目录为真
-e file
文件存在为真
-f file
是常规文件为真
-g file
文件存在,且set-group-id为真
-h file
文件为符号链接为真
-k file

-p file

-r file
可读文件为真
-s file
文件大于0为真
-S file 是套接字文件为真
-t fd

-u file


-w file
文件可写为真
-x file
文件可执行为真
-G file

-L file
文件为符号链接为真
-N file
最后一次被读取之后修改为真
-O file

file1 -ef file2

硬链接文件为真

设备号一致、节点号一致

file1 -nt file2

file1的“修改时间”更新为真

file1存在,file2不存在为真

file1 -ot file2

file1的“修改时间”更旧为真

file1不存在,file2存在为真
-o optname

-v varname

-z string
字符串长度为零时为真

string

-n string

字符串长度非零时为真

string1 = string2

字符串相等时为真
string1 != string2
字符串不相等时为真
string1 < string2
strring1排序在前时为真
string1 > string2

int1 -eq int2
数字相等
int1 -ge int2
大于等于
int1 -gt int2 大于
int1 -le int2 小于等于
int1 -lt int2 小于
int1 -ne int2 数字不等
EXPR1 -a EXPR2
与关系
EXPR1 -o EXPR2 或关系
! EXPR 取反

======================================================

例子:字符串长度“非零”为真

[view@payqa2 ~]$ string=""
[view@payqa2 ~]$ [ $string ] && echo "true"
[view@payqa2 ~]$ string="hello"
[view@payqa2 ~]$ [ $string ] && echo "true"
true