一、条件判断

1、根据运行的命令的状态结果

2、测试表达式

test EXPRESSION

[ EXPRESSION ]    命令          #[ ]两边一定得有空格

` EXPRESSION `   关键字, 通用性更好      #` ` 两边一定得有空格


3、常用的测试类型

整数测试:

gt,ge,lt,le,eq,ne

      二元测试

      做数值大小比较,所有不要给变量引用加引用

$A -gt $B       是否大于,是则为真,不是则为假

$A -ge $B      是否大于等于

A -lt B            是否小于

A -le B           是否小于等于

A -eq B          是否等于

A -ne B          是否不等于


字符串测试:(字符串要使用引号引起来)

"$A">"$B":是否大于        #ASII数值越大,字符比较越大

"$A"<"$B":是否小于

"$A" == "$B":是否等于;

"$A" != "$B":是否不等于;


-z "$A":是否为空;空则为“真”,否则为“假”

-n "$A":是否不空;不空则“真”,空则为“假”

=~:左侧是字符串,右侧是一个模式,判定左侧的字符串能否被右侧的模式所匹配,一般在` `中使用,模式中可以使用行首,行尾匹配,但模式不能加引号

[[ "string" =~ PATTERN ]]  #不能使用-a,-o,只支持扩展正则表达式


文件测试:

       测试文件是否存在性以及属性

-e $file:文件是否存在,存在为真

-a $file:文件是否存在          #-e和-a用法一样

-f $file:是否存在且为普通文件

-d $file:是否存在且为目录

-L $file:是否存在且为链接文件

-h $file:是否存在且为链接文件

-b $file:是否存在且为块设备文件

-c $file:是否存在且为字符设备文件

-s $file:文件存在并且大小大于0为真(就是存在且不为空)

-p $file:是否存在且为管道文件

-S $file:是否为套接字设备


-r $file:当前用户对文件是否拥有读权限

-w $file:写

-x $file:执行

-u $file:SUID

-g $file:SGID

-k $file:sticky


-O $file:当前用户是否为文件的属主

-G $file:属组


双目操作符:

   $file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;                     

   $file1 -ot $file2: file1是否旧于file2, 

   $file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;


组合测试条件(短路操作 )

条件间逻辑运算:与,或,非

逻辑与:多个条件同时满足       

[ CONDITION1 ] && [ CONDITION2 ]

[ CONDITION1 -a CONDITION2 ]

[[ CONDITON1 && CONDITION2 ]]

注意:前面1个单双中括号都可以,中间的只能使用单中括号(-o也一样),&&只能使用双中括号中

逻辑或:多个条件中有一个满足即为真

[ CONDITION1 ] || [ CONDITION2 ]

[ CONDITION1 -0 CONDITION2 ]

[[ CONDITON1 || CONDITION2 ]]

非: [[ ! CONDITION ]] 等价于 ! [ CONDITION ]       #单双中括号都可


Shell表达式与运算符参考:http://lizhenliang.blog.51cto.com/7876557/1882219


二、条件判断语句

什么是条件语句?

       是指一种表示假设的主从复合句,一般由连词 if 引导的条件从句引出某种假设,再由主句表示基于这种假设下的反馈. “如果[或假如]……那么……”  “当.....那么...”,选择执行

1、if

单分支if语句:

if   CONDITION

then  if-true-分支

fi                   

         当CONDITION成立时执行if-true-分支,否则退出

[root@BAIYU_207 shell]# bash -x 1.sh
+ '[' -d /etc/sysconfig/network-scripts ']'
+ echo exist
exist
[root@BAIYU_207 shell]# cat 1.sh
#!/bin/bash
if [ -d /etc/sysconfig/network-scripts ]
then echo "exist"
fi

双分支if语句:

   if CONDITION

   then if-true-分支

   else  if-false-分支

   fi

          当CONDITION成立时执行if-true-分支,否则执行if-false-分支

[root@BAIYU_207 shell]# bash -x 1.sh
+ '[' -f /etc/sysconfig/network-scripts ']'
+ echo 'not exist'
not exist
[root@BAIYU_207 shell]# cat 1.sh
#!/bin/bash
if [ -f /etc/sysconfig/network-scripts ]
then echo "exist"
else echo "not exist"
fi

多分支if语句:

   if CONNITION1

   then if-true-分支1

   elif CONNITION2

   then if-true-分支2

   elif CONNITION3

   then if-true-分支3

   else if-false-分支

   fi

       当CONNITION1成立时执行if-true-分支1,当CONNITION2成立时执行if-true-分支2,当所有条件都不成立则执行if-false-分支

[root@BAIYU_207 shell]# bash -x 1.sh     
+ '[' -f /etc/sysconfig/network-scripts ']'
+ '[' '!' -c /dev/zero ']'
+ '[' -n /dev/null ']'
+ echo cccccccccc
cccccccccc
[root@BAIYU_207 shell]# cat 1.sh
#!/bin/bash
if [ -f /etc/sysconfig/network-scripts ]
then echo "aaaaaaaaaa"
elif [ ! -c /dev/zero ]
then echo "bbbbbbbbbbbbb"
elif [ -n /dev/null ]
then echo "cccccccccc"
else echo "not exist"
fi

2、case

   简洁版多分支if语句

使用场景:判断某变量的值是否为多种情形中的一种时使用

语法:

    case $VARIABLE in      #这里的变量要使用$引用,引用变量的值和下面的PATTERN比较

    PATTERN1)

           分支1

           ;;

    PATTERN2)

           分支2

            ;;

     ...

       *)              #上面的都没匹配到,则使用下面的语句

           分支n

            ;;        #这里可省略

      esac


csse语句中PATTERN可使用glob模式的通配符      

*: 任意长度的任意字符;

?: 任意单个字符;

[]: 指定范围内的任意单个字符;

a|b: 多选1;

  


1、写一个脚本可接受以下四个参数并执行相应的操作

   start:创建文件/var/lock/subsys/SCRIPT_NAME,

   stop:删除此文件

   restart:删除此文件并重新创建此文件,

   status:如果此文件存在,显示为running,否则显示为“stop”

[root@Note3 ~]# cd /tmp/src
[root@Note3 src]# cat script.sh 
#/bin/bash

prog=$(basename $0)
file="/var/lock/subsys/$prog"

if [[ "$1" == "start" ]]        
then if [ -e $file ]
     then echo"The $prog is started yet."
     else touch $file && echo "The $prog start success..."||echo "The $prog start failed"
     fi
elif [ "$1" == "stop" ]     #测试发现这里$1不加双引号的话,如果$1的值为空就会报错,但是[[ ]]中不会报错,所以建议和字符串相关的都加上双引号和使用[[ ]]可以避免很多错误
then if [ -e $file ]
     then rm -f $file && echo "The $prog stop success..."||echo "The $prog stop failed"
     else echo "The $prog is stop yet."
     fi
elif [ "$1" == "restart" ]
then if [ -e $file ]
     then rm -f $file && echo "The $prog stop success..." || echo "The $prog stop failed"
          touch $file && echo "The $prog start success..."  || echo "The $prog start failed"
    else touch $file && echo "The $prog start success..." || echo "The $prog start failed"
     fi
elif [ "$1" == "status" ]
then if [ -e $file ]
     then echo "The $prog is running"
     else echo "The $prog stopped"
     fi
else echo "Usage: $prog start|stop|restat|status"
fi

测试:

[root@Note3 src]# cd /var/loc
local/ lock/  
[root@Note3 src]# cd /var/lock/subsys/
[root@Note3 subsys]# ls script.sh
ls: 无法访问script.sh: 没有那个文件或目录
[root@Note3 subsys]# bash /tmp/src/script.sh status
The script.sh stopped
[root@Note3 subsys]# bash /tmp/src/script.sh start
The script.sh start success...
[root@Note3 subsys]# ls script.sh
script.sh
[root@Note3 subsys]# bash /tmp/src/script.sh status
The script.sh is running
[root@Note3 subsys]# bash /tmp/src/script.sh stop
The script.sh stop success...
[root@Note3 subsys]# bash /tmp/src/script.sh status
The script.sh stopped
[root@Note3 subsys]# ls script.sh
ls: 无法访问script.sh: 没有那个文件或目录
[root@Note3 subsys]# bash /tmp/src/script.sh stop
The script.sh is stop yet.
[root@Note3 subsys]# bash /tmp/src/script.sh restart
The script.sh start success...
[root@Note3 subsys]# ls script.sh
script.sh
[root@Note3 subsys]# bash /tmp/src/script.sh restart
The script.sh stop success...
The script.sh start success...
[root@Note3 subsys]# ls script.sh
script.sh
[root@Note3 subsys]# bash /tmp/src/script.sh restartsb
Usage: script.sh start|stop|restat|status

2、用case语句改写练习2的脚本

[root@Note3 src]# cp script.sh script1.sh 
[root@Note3 src]# vim script1.sh

[root@Note3 src]# cat script1.sh 
#/bin/bash

prog=$(basename $0)
file="/var/lock/subsys/$prog"

case $1 in
"start")
    if [ -e $file ]
    then echo "The $prog is started yet."
    else touch $file && echo "The $prog start success..."||echo "The $prog start failed"
    fi
;;
"stop")
    if [ -e $file ]
    then rm -f $file && echo "The $prog stop success..."||echo "The $prog stop failed"
    else echo "The $prog is stop yet."
    fi
;;
"restart")
    if [ -e $file ]
     then rm -f $file && echo "The $prog stop success..." || echo "The $prog stop failed"
          touch $file && echo "The $prog start success..."  || echo "The $prog start failed"
    else touch $file && echo "The $prog start success..." || echo "The $prog start failed"
    fi
;;
"status")
    if [ -e $file ]
    then echo "The $prog is running"
    else echo "The $prog stopped"
    fi
;;
*)
echo "Usage: $prog start|stop|restat|status"
esac

测试:

[root@Note3 src]# bash script1.sh
Usage: script1.sh start|stop|restat|status
[root@Note3 src]# bash script1.sh status
The script1.sh stopped
[root@Note3 src]# bash script1.sh start
The script1.sh start success...
[root@Note3 src]# bash script1.sh start
The script1.sh is started yet.
[root@Note3 src]# bash script1.sh status
The script1.sh is running
[root@Note3 src]# bash script1.sh restart
The script1.sh stop success...
The script1.sh start success...
[root@Note3 src]# bash script1.sh stop
The script1.sh stop success...
[root@Note3 src]# bash script1.sh restart
The script1.sh start success...
[root@Note3 src]#

3、写一个简单的脚本

 提示用户输入一个任意字符

 能判断此字符是数字、字母或特殊字符

[root@Note3 src]# cat case1.sh 
#!/bin/bash

read -p "Please input a char: " char

case $char in 
[a-z])
    echo "The $char is a character"
;;
[0-9])
    echo "The $char is a number"
;;
*)
    echo "The $char is a special character"
;;
esac
[root@Note3 src]# bash case1.sh
Please input a char: 1
The 1 is a number
[root@Note3 src]# bash case1.sh
Please input a char: a  
The a is a character
[root@Note3 src]# bash case1.sh
Please input a char: sb
The sb is a special character

4、写一个脚本,能对/etc/目录进行打包备份,备份位置为/backup/etc-时间.后缀

 显示如下菜单给用户:

    xz)xz compress

    gz)gzip compress

   bzip2)bzip2 compress

  根据用户指定的压缩工具使用tar打包压缩

  默认为xz,用户输入错误则需要用户重新输入

[root@Note3 src]# cat case2.sh 
#/bin/bash

cat << EOF
xz) xz compress
gzip) gzip compress
bzip2) bzip2 compress
EOF

read -p "Please your option: " option
option=${option:-xz}

case $option in
"xz") 
    tar Jcf /tmp/etc-`date +'%F-%H-%M-%S'`.tar.xz /etc/ 
;;
"gzip")
    tar zcf /tmp/etc-`date +'%F-%H-%M-%S'`.tar.gz /etc/ 
;;
"bzip2")
    tar jcf /tmp/etc-`date +'%F-%H-%M-%S'`.tar.bz2 /etc/ 
;;
*)
     echo "Useage: `basename $0` xz|gzip|bzip2"
esac