shell编程中,当使用if语句时,总是涉及到条件的判断。下面来讨论下条件判断的各种情况。
1. 条件为语句
例如:当目录下有sam开头的文件时,输出hi,it's here.
if ls sam* &> /dev/null; then echo "Hi,it's here." fi
当条件为语句时,直接跟在if后面,如果语句执行成功,返回0,表示真,然后执行语句块中的语句。
再来个例子,查看本机中是否有hive的用户,如果有,显示hive的uid和bash类型。
if grep "^hive" /etc/passwd; then grep "^hive" /etc/passwd | cut -d: -f1,3,7 fi
2. 条件为变量判断时
即判断某个变量是否符合某个条件的时候,判断语句有下面三种类型
[ expression ]
[[ expression ]]
test expression
根据变量类型,分为以下几种情况讨论:
(1) 整数测试
当变量为整数时,可以选择[ expression ]这种格式的语句。
expression可以写成这样:数值1 比较符号 数值2($A 比较符号 $B)
比较符号有下面这些:
大于:-gt, 例如 $A -gt $B
大于或等于:-ge
等于:-eq
小于:-lt
小于或等于:-le
不等于:-ne
还是看例子吧
例1;写一个脚本,生成两个随机数,比较其大小;显示大数;
bash有个内置变量:$RANDOM
#!/bin/bash # A=$RANDOM B=$RANDOM if [ $A -ge $B ]; then echo "Max number is $A." else echo "Max number is $B." fi
例2:写一脚本,随机生成一个整数,判定,显示其奇偶性
#!/bin/bash # A=$RANDOM if [ $[$A%2] -eq 0 ]; then echo "$A: Even" else echo "$A: Odd" fi
(2) 字符测试
变量为字符时,进行字符测试。
bash字符测试时,从左至右逐字符比较
>: 大于
<: 小于
==: 等于 (前三者用的格式都是[ expression ])
=~: 判断左边的字符串是否能够被右边的模式所匹配;通常用于[[ expression ]];
[[ $opt1 =~ $opt2 ]],一般做行首、行尾锚定;不要加引号;
单目:
-z $STRING: 为空则为真,不空则为假;
-n $STRING: 为空则为假,不空则真;
例1:写一个脚本,判定用户的shell是否为bash
#!/bin/bash # Shell=`grep "^$1:" /etc/passwd | cut -d: -f7` if [ -z $Shell ]; then echo "No such user or User's shell is null." exit 10 fi if [ "$Shell" == "/bin/bash" ]; then echo "Bash User." Ret=0 else echo "Not Bash User." Ret=9 fi exit $Ret
例2:通过参数传递一个字符串给脚本,如果传递的字符串为“memory”或“Memory”,就以MB为单位显示当前主机的内存信息
#!/bin/bash # if [[ $1 =~ [Mm]emory$ ]]; then free -m else cat /proc/uptime fi
(3) 文件测试
当变量为文件路径或目录路径时,判断其是否存在,是否是普通文件等都需要文件测试
操作符 文件路径
-f: 测试其是否为普通文件,即ls -l时文件类型为-的文件;
-d: 测试其是否为目录文件,即ls -l时文件类型为d的文件;
-e: 测试文件是否存在;存在为真,否则为假;
-r: 测试文件对当前用户来说是否可读;
-w: 测试文件对当前用户来说是否可写;
-x: 测试文件对当前用户来说是否可执行;
-s: 测试文件大小是否不空,不空则真,空则假
例1:
写一个脚本:可以接受一个参数,其使用形式如下:
script.sh {start|stop|restart|status}
如果参数为start,创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
如果参数为restart,则删除文件/var/lock/subsys/script后重新创建,并显示“Restarting script successfully.”;
如果参数为status,那么:
如果/var/lock/subsys/script文件存在,则显示为“script is running.”
否则,则显示为“script is stopped.”
其它任何参数:则显示“script.sh {start|stop|restart|status}”
进一步:修改start的机制为:
如果参数为start,且/var/lock/subsys/script文件不存在,则创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
否则,显示“script is already running.”
进一步:修改stop的机制为:
如果参数为stop,且/var/lock/subsys/script文件存在,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
否则,显示“script is stopped yet.”
#!/bin/bash # SvcName=`basename $0` LockFile="/var/lock/subsys/$SvcName" if [ $# -lt 1 ]; then echo "Usage: $SvcName {start|stop|restart|status}" exit 3 fi if [ $1 == 'start' ]; then if [ -e $LockFile ]; then echo "$SvcName is running." else touch $LockFile &> /dev/null echo "Starting $SvcName successfully." fi elif [ $1 == 'stop' ]; then if [ -e $LockFile ];then rm -f $LockFile &> /dev/null echo "Stopping $SvcName finished." else echo "$SvcName is stopped yet." fi elif [ $1 == 'restart' ]; then rm -f $LockFile &> /dev/null touch $LockFile &> /dev/null echo "Restarting $SvcName successfully." elif [ $1 == 'status' ]; then if [ -e $LockFile ]; then echo "$SvcName is running." else echo "$SvcName is stopped." fi else echo "Usage: $SvcName {start|stop|restart|status}" exit 4 fi
3. 条件判断中的组合符
当判断的条件不只一个时,需要用到组合符
-a 和,表示两端条件都要满足
-o 并,表示两端条件只要满足一个就好
! 非,与后面的条件相反
例1: 输入一个数字,若大于1并且小于100,输出"available",否则输出"invalid input"
#!/bin/bash read -p "please input a number: " num if [ $num -gt 1 -a $num -lt 100 ];then echo "available" else echo "invalid input" fi
4. 短路运算符
短路操作:只要前半段已经可以决定最终结果,后半段就不再运算;
与运算:
假 && {真|假} = 假
或运算:
真 || (真,假) = 真
例1:判断目录/tmp/test是否存在,不存在的话,就新建该目录,存在的话,就输出"derictory exists"
[ -d /tmp/test ] || mkdir /tmp/test && echo "directory exists"