一、组合条件判断

组合条件测试是指可以将多个条件组合起来进行判断,条件和条件之间有逻辑关系。例如判断一个数是否大于3,并且小于9,这里大于3是一个条件,小于9也是一个条件,这两个条件必须同时满足。同时满足即为逻辑关系。通常逻辑关系有以下几种:

与:-a,当指定多个条件时,默认为与关系

或:-o

非:!,这是个单目操作符

 

如判断一个UID是否大于1,且小于499的写法如下

[root@localhost tutor]# Uid=300

[root@localhost tutor]# [ $Uid -ge 1 ]

[root@localhost tutor]# echo $?

0

[root@localhost tutor]# [ $Uid -le 499 ]

[root@localhost tutor]# echo $?

0

[root@localhost tutor]# [ $Uid -ge 1 -a $Uid -le 499 ]

# 使用-a表示两个与关系的条件,必须同时满足

[root@localhost tutor]# echo $?

0

[root@localhost tutor]# Uid=3000

[root@localhost tutor]# [ $Uid -ge 1 -a $Uid -le 499 ]

[root@localhost tutor]# echo $?

1

如判断一个UID是否等于0,或者大于的写法如下

[root@localhost tutor]# Uid=300

[root@localhost tutor]# [ $Uid -eq 0 -o $Uid -ge 500 ]

# 使用-o表示两个或关系的条件,只需要满足其一即可

[root@localhost tutor]# echo $?

1

[root@localhost tutor]# Uid=3000

[root@localhost tutor]# [ $Uid -eq 0 -o $Uid -ge 500 ]

[root@localhost tutor]# echo $?

0

判断一个UID是否不等于0,写法如下:

[root@localhost tutor]# Uid=0

[root@localhost tutor]# [ ! $Uid -eq 0 ]

# 使用! 表示取反,这里对Uid等于0的判断结果进行取反,即为Uid不等于0

[root@localhost tutor]# echo $?

1

[root@localhost tutor]# [ $Uid -ne 0 ]

# 这里判断Uid是否不等于0

[root@localhost tutor]# echo $?

1

 

. 写一个脚本,通过参数传递一个字符串给脚本,如果传递的字符串为“memory”或“Memory”,就以MB为单位显示当前主机的内存信息;否则,就显示/proc/uptime文件的内容。

[root@localhost tutor]# vim memory1.sh

#!/bin/bash
if [ $1 =="memory" -o $1 == "Memory" ]; then
# 这里不再使用模式匹配了,而采用-o或关系来进行组合条件判断
        free -m
else
        cat /proc/uptime
fi

[root@localhost tutor]# bash -x memory1.sh memory

+ '[' memory== memory -o memory == Memory ']'
+ free -m
             total       used       free    shared    buffers     cached
Mem:           996        511        484         0         57        160
-/+buffers/cache:        293        702
Swap:         2015          0       2015

[root@localhost tutor]# bash -x memory1.sh Memory

+ '[' Memory== memory -o Memory == Memory ']'
+ free -m
             total       used       free    shared    buffers     cached
Mem:           996        511        484        0         57        160
-/+buffers/cache:        293        702
Swap:         2015          0       2015

[root@localhost tutor]# bash -x memory1.sh abc

+ '[' abc ==memory -o abc == Memory ']'
+ cat/proc/uptime
50889.6250151.85

 

上面的逻辑关系,是针对条件组合的情况,两个或多个命令的运行结果也可以组合判断,其逻辑关系有如下几种:

&&:

||:或

!:

写一脚本,给定用户,如果UID等于GID,就显示为“Good Guy”,否则显示为“BadGuy”如果其不存在,就退出脚本。

[root@localhost tutor]# vim if_user_lg.sh

#!/bin/bash
 
if ! id $1&> /dev/null; then
# 过去使用双分支if来判断不存在的情况,这里使用!表示判断命令是否执行不成功
        echo "No such user."
        exit 6
fi
 
if [ `id -u$1` -eq `id -g $1` ]; then
        echo "Good Guy"
else
        echo "Bad Guy"
fi

[root@localhost tutor]# bash -x if_user_lg.sh root

+ id root
++ id -u root
++ id -g root
+ '[' 0 -eq 0']'
+ echo 'GoodGuy'
Good Guy

[root@localhost tutor]# echo $?

0

[root@localhost tutor]# bash -x if_user_lg.sh roott

+ id roott
+ echo 'Nosuch user.'
No such user.
+ exit 6

[root@localhost tutor]# echo $?

6

 

二、多分支if语句

前文中涉及到的条件判断语句,只有单分支和双分支的情况,事实上bash也支持多分支的条件判断,多分支的if语句是对双分支if语句的扩展。多分支if语句提供多个if条件,但仅执行其中一个语句,其语法格式为:

if 条件1; then

语句1

语句2

...

elif 条件2; then

语句1

语句2

...

elif 条件3; then

语句1

语句2

...

else

语句1

语句2

...

fi

 

下面来举例演示多分支条件语句的使用方法:

 

1. 写一个脚本:判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。如果其生产商为GenuineIntel,就显示其为Intel公司;如果其生产商为AuthenticAMD,就显示其为AMD公司;

否则,就显示无法识别

 

[root@localhost tutor]# vim if_cpu1.sh

#!/bin/bash
#
Vendor=`grep"vendor_id" /proc/cpuinfo | uniq | cut -d: -f2`
 
if [[ $Vendor=~ [[:space:]]*GenuineIntel$ ]]; then
        echo "intel"
elif [[$Vendor =~ [[:space:]]*AuthenticAMD$ ]]; then
# 使用了elif进一步判断是否为AMD
        echo "AMD"
else
        echo "Unknown"
fi

 

[root@localhost tutor]# bash -x if_cpu1.sh

++ cut -d: -f2
++ uniq
++ grepvendor_id /proc/cpuinfo
+ Vendor='GenuineIntel'
+ [[  GenuineIntel =~ [[:space:]]*GenuineIntel$ ]]
+ echo intel
intel

 

2. 通过参数传递给脚本一个字符串,如Fedora,Gentoo, Redhat,判断Linux发行版所处理主流发行系列:如果为fedora,centos, redhat,就显示RedHat;如果为suse, opensuse,就显示为SUSE; 如果为ubuntu, mint,  debian,就显示为Debian;否则,显示为其它

 

[root@localhost tutor]# vim version.sh

#!/bin/bash
#
if [ $1 =="fedora" -o $1 == "centos" -o $1 == "redhat" ];then
        echo "RedHat"
elif [ $1 =="suse" -o $1 == "opensuse" ]; then
        echo "SUSE"
elif [ $1 =="ubuntu" -o $1 == "mint" -o $1 == "debian" ];then
        echo "Debian"
else
        echo "Others"
fi

[root@localhost tutor]# bash version.sh redhat

RedHat

[root@localhost tutor]# bash version.sh mint

Debian

[root@localhost tutor]# bash version.sh opensuse

SUSE

[root@localhost tutor]# bash version.sh abc

Others

 

3. 写一个能用来创建其他脚本的脚本该脚本必须接受三个参数,最后一个参数为文件名,但参数可变化,形如:

          script.sh  -a abc /u01/scripts/test1.sh

          script.sh  -d 2013-07-19 /u01/scripts/test1.sh

          script.sh  -D 'some infomation'  /u01/scripts/test1.sh

此脚本能够创建/u01/scripts/test1.sh文件,并且,如果给出了-a abc,则文件前两行为:

#!/bin/bash

# Author:abc

如果给出了-d 2014-07-23,则文件前两行为:

#!/bin/bash

# Date: 2013-07-23

如果给出了-D "someinfomation",则文件前两行为:

#!/bin/bash

#Description: some infomation

其它任何参数,均提示错误并退出

 

以下为该脚本的第一版:

——————————————————————————————————

[root@localhost ~]# vim mkscript

#!/bin/bash
#
if [ $# -ne 3]; then
        echo "the number of arguements iswrong."
        exit 4
fi
 # 判断是否传递了3个参数
 
echo'#!/bin/bash' >> $3
     # 创建脚本,该脚本以第三个参数为文件名,并将”#!/bin/bash”写入脚本的第一行
 
if [ $1 =='-a' ]; then
        echo "# Author: $2" >>$3
# 如果第一个参数为 -a,则将第二个参数作为作者,写入脚本的第二行
elif [ $1 =='-d' ]; then
        echo "# Date: $2" >> $3
# 如果第一个参数为 -d,则将第二个参数作为时间,写入脚本的第二行
elif [ $1 =='-D' ]; then
        echo "# Description: $2">> $3
# 如果第一个参数为 -D,则将第二个参数作为描述,写入脚本的第二行
else
        echo "Unkown Option, ignoreit."
        rm -f $3
 # 由于已经创建了$3这个文件,且往文件中写入了内容,故如果参数传递错误,应先删除文件
 exit 5
fi
 
vim + $3
# 如果脚本能够被创建,则用vim打开脚本,当用户在vim编辑器中完成编辑并保存之后,
# 会返回到当前的脚本,接着执行下面的语句
if bash -n $3> /dev/null; then
# 用户编写完 $3这个文件后判断脚本是否有语法错误,若没有则添加执行权限
        chmod +x $3
else
        echo "Sytax wrong in $3."
# 如果有语法错误,则提示用户
fi

——————————————————————————————————

脚本到这里就编写完成了,下面执行该脚本以检验其是否完成了需要的功能

[root@localhost ~]# chmod +x mkscript

[root@localhost ~]# bash -n mkscript

[root@localhost ~]# ./mkscript /tmp/a.sh

the number ofarguements is wrong.
# 只传递了一个参数,故脚本中断执行


[root@localhost ~]# ./mkscript -a mickey /tmp/a.sh

# 传递3个参数,脚本能够成功执行

[root@localhost ~]# cat /tmp/a.sh

#!/bin/bash
# Author:mickey
# 脚本/tmp/a.sh已经自动添加了两行内容


[root@localhost ~]# ./mkscript -d 2014-07-24 /tmp/b.sh

[root@localhost ~]# cat /tmp/b.sh

#!/bin/bash
# Date:2014-07-24

[root@localhost ~]# ./mkscript -D "Toy Program"/tmp/c.sh

[root@localhost ~]# cat /tmp/c.sh

#!/bin/bash
# Description:Toy Program

[root@localhost ~]# ./mkscript -m hello /tmp/d.sh

Unkown Option,ignore it.
# 故意传递错误参数,以检验文件是否会被创建


[root@localhost ~]# ls /tmp

a.sh c.shkeyring-Xi9NCS  orbit-gdm  pulse-uP5T8Y6V6nIN  virtual-root.nBhtJw virtual-root.q9Sgpu  yum.log
b.sh keyring-bgxXAq keyring-xva5ss  orbit-root  pulse-yCmeAwocSW1U  virtual-root.plTHoO  irtual-root.rQ0Eab
# 没有看到 /tmp/d.sh这个文件,说明它已经被删除了


[root@localhost ~]# ./mkscript -a mickey /tmp/a.sh

#!/bin/bash
# Author:hello
~                                                                                                                             
~
# 如果参数都传递正确,则会自动打开脚本让用户编写

[root@localhost ~]# ./mkscript -D "Syntax test"/tmp/e.sh

#!/bin/bash
# Description:Syntax test
 
if [ $1 -eq 0]; then
        echo Hello
 
~                                                                                                                             
~                                                                                                                              
# 故意不写fi,来检测该脚本中的语法检查功能是否实现了。
/tmp/e.sh:line 7: syntax error: unexpected end of file
Sytax wrong in/tmp/e.sh.

[root@localhost ~]# ./mkscript -D "Syntax right"/tmp/f.sh

#!/bin/bash
# Description:Syntax right
if [ $1 -eq 0]; then
        echo hello
else
        echo world
fi
# 这次创建一个正确的脚本,用来检查是否给该脚本添加了执行权限


[root@localhost ~]# ls -l /tmp/f.sh

-rwxr-xr-x. 1 root root 94 Jul 12 07:40 /tmp/f.sh
# 可以看到f.sh这个文件已经有执行权限了


[root@localhost ~]# /tmp/f.sh 0

hello
# 可以直接执行/tmp/f.sh这个脚本,为其传递参数0