shell中的条件判断

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 ]       为空
比较时“==”两边保留空格,赋值时取消空格。
 

 

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

$ 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

1.1.2.“-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",	[ -n $K]	'
judge $K
echo -ne 'S="",		[ -n $S]	'
judge $S
$ ./string_n.sh
K="hello",      [ -n $K]        Execute then. true
S="",           [ -n $S]        Execute then. true

  测试结果,令人吃惊!

 

1.1.3.把上边“-n”替换成“-z”

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

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

 

1.1.4.测试位置变量的有无

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

# 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)是否存在。

 

1.1.5.比较时竟然可以用“=”

  阅读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.1.6.错误

  这段代码是有问题的,运行后会懵……

if [ '-t'='$1' ]; then
        echo "ceshi: -t."
fi

if [ "-f"==$1 ]; then
        echo "ceshi: -f."
fi

 效果如下:

[root@file work]# ./test_para.sh -f
ceshi: -t.
ceshi: -f.

从运行效果看,两个 if 语句都成功匹配了。正确的结果应该是不匹配的。问题就出在“=”两边没有使用空格空开。

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

表达式用法

exprtest[说明

$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

  例子:比较返回值

check_it () {
        if [ "true" == $1 ]
        then
                return 0
        else
                return 1
        fi  
}


if [[ 1 != $(check_it "true") ]]#可以带双引号,也可以不带,1都可以正确识别;
then
        echo "false"
fi

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.

d/D show disks usages.

m/M show memory usages.

s/S show swap usages.


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 "	Unkown 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

[web@h p]$ [ -d $LOCALDIRECTORY ] && $RM -fr $LOCALDIRECTORY
[web@h p]$ [ ! -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 取反

 

 2.应用示例


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

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

   移动文件 在 Shell 脚本中处理通配符,比较时 = 两边需要有空格,判断位置参数存在与否,逻辑判断作为条件判断,屏蔽命令输出。

 1 # variables
 2 DESTDIR=/ftp/school/teacher
 3 SOURDIR=/view
 4 USERNAME=develop
 5 GROUPNAME=develop
 6 
 7 if [ ! -z $1 ]; then
 8         # list file in destation directory.
 9         if [ -f = $1 ]; then
10                 ls -l $DESTDIR
11 
12                 exit 1
13         fi
14 
15         # clear files in destation directory.
16         if [ --clear = $1 ]; then
17                 env rm -fr ${DESTDIR}/*
18 
19                 exit 2
20         fi
21 
22         # test zip file ok.
23         if [ -t = $1 ]; then
24                 for tf in $(ls -1 $DESTDIR); do
25                         env file ${DESTDIR}/${tf} | grep -F "Zip archive data" &>/dev/null && zip -T ${DESTDIR}/$tf
26                 done
27 
28                 exit 3
29         fi
30 else
31         # Move to destation directory.
32         ls -1 ${SOURDIR}/* 2>/dev/null && env mv -v -t $DESTDIR ${SOURDIR}/* && chown -R $USERNAME:$GROUPNAME $DESTDIR
33         exit 0
34 fi
View Code
一切代码都是为了生活,一切生活都是调剂
原文地址:https://www.cnblogs.com/argor/p/7909171.html