Linux流程控制语句之if

语法:

if ….; then
  ….
elif ….; then
  ….
else
  ….
fi

[ -f “somefile” ] :判断是否是一个文件
[ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限
[ -n “$var” ] :判断$var变量是否有值
[ “$a” = “$b” ] :判断$a和$b是否相等
-r file     用户可读为真
  -w file     用户可写为真
  -x file     用户可执行为真
  -f file     文件为正规文件为真
  -d file     文件为目录为真
  -c file     文件为字符特殊文件为真
  -b file     文件为块特殊文件为真
  -s file     文件大小非0时为真
  -t file     当文件描述符(默认为1)指定的设备为终端时为真

含条件选择的shell脚本 对于不含变量的任务简单shell脚本一般能胜任。但在执行一些决策任务时,就需要包含if/then的条件判断了。shell脚本编程支持此类运算,包括比较运算、判断文件是否存在等。基本的if条件命令选项有: - eq —比较两个参数是否相等(例如,if [ 2 –eq 5 ])
-ne —比较两个参数是否不相等
-lt —参数1是否小于参数2
-le —参数1是否小于等于参数2
-gt —参数1是否大于参数2
-ge —参数1是否大于等于参数2
-f — 检查某文件是否存在(例如,if [ -f “filename” ])
-d — 检查目录是否存在
几乎所有的判断都可以用这些比较运算符实现。脚本中常用-f命令选项在执行某一文件之前检查它是否存在。 ##################################################################
判断文件是否存在

#!/bin/sh
YACCESS=date -d yesterday +%Y%m%d
FILE=”access_$YACCESS.log.tgz”
cd /data/nginx/logs
if [ -f “$FILE” ];then
echo “OK”
else
echo “error $FILE” > error.log
mail -s “$FILE backup fail” xxxx@yyyy.com <error.log
fi

###############

#!/bin/sh

#
DIR=/data/img_cache
DAY=date +"%Y-%m-%d %H:%M"
NUM=ls $DIR |wc -l
DIRNAME=ls $DIR| grep leveldb | head -n 1 | awk '{print $NF}'
if [[ $NUM -gt 3 ]];then
rm -rf $DIR/$DIRNAME
echo “———$DAY—-($DIR)———————–” >> /tmp/img_cache.log
echo “$DIRNAME Deleted successful” >> /tmp/img_cache.log
fi
补充:文件测试操作:
返回true,如果:
-e 文件存在
-a 文件存在(已被弃用)
-f 被测文件是一个regular文件(正常文件,非目录或设备)
-s 文件长度不为0
-d 被测对象是目录
-b 被测对象是块设备
-c 被测对象是字符设备
-p 被测对象是管道
-h 被测文件是符号连接
-L 被测文件是符号连接
-S(大写) 被测文件是一个socket
-t 关联到一个终端设备的文件描述符。用来检测脚本的stdin[-t0]或[-t1]是一个终端
-r 文件具有读权限,针对运行脚本的用户
-w 文件具有写权限,针对运行脚本的用户
-x 文件具有执行权限,针对运行脚本的用户
-u set-user-id(suid)标志到文件,即普通用户可以使用的root权限文件,通过chmod +s file实现
-k 设置粘贴位
-O 运行脚本的用户是文件的所有者
-G 文件的group-id和运行脚本的用户相同
-N 从文件最后被阅读到现在,是否被修改
f1 -nt f2 文件f1是否比f2新
f1 -ot f2 文件f1是否比f2旧
f1 -ef f2 文件f1和f2是否硬连接到同一个文件
二元比较操作符,比较变量或比较数字
整数比较:
-eq 等于 if [ “$a” -eq “$b” ]
-ne 不等于 if [ “$a” -ne “$b” ]
-gt 大于 if [ “$a” -gt “$b” ]
-ge 大于等于 if [ “$a” -ge “$b” ]
-lt 小于 if [ “$a” -lt “$b” ]
-le 小于等于 if [ “$a” -le “$b” ]
< 小于(需要双括号) (( “$a” < “$b” ))
<= 小于等于(…) (( “$a” <= “$b” ))

大于(...)                      (( "$a" > "$b" ))

= 大于等于(…) (( “$a” >= “$b” ))
字符串比较:
= 等于 if [ “$a” = “$b” ]
== 与=等价
!= 不等于 if [ “$a” = “$b” ]
< 小于,在ASCII字母中的顺序:
if [[ “$a” < “$b” ]]
if [ “$a” \< “$b” ] #需要对<进行转义
大于
-z 字符串为null,即长度为0
-n 字符串不为null,即长度不为0

二、语法

在“判断条件”这个字段里可以直接写入bash下的命令、也可以写成条件测试
在判断条件中要进行条件测试:

条件测试方式:

“[ expression ]”一个中括弧里写表达式,
“[[ expression ]]”两个中括弧里写上表达式
“test expression”
“bash命令”

条件测试的类型:

整数测试

expression:[ 数值1 比较符 数值2 ]
比较符一般有以下几种:
大于:-gt(greater than),大于等于:-ge(greater equal),小于:-lt(less than),小于等于:le(less equal),不等于:-ne(not equal)

字符测试

"\>":大于
"\<":小于
"=="或者"=":等于
"=~":判断左边的字符串能否被右边的模式所匹配,通常用于[[ expression ]]

单目测试:

-z:格式为"[ -z $STRING ]",表示为空值时则为真,不为空值时则为假
-n:格式为"[ -n $STRING ]",表示为空值时则为假,不为空值时则为真

文件、目录测试

-d:测试目录是否存在
-f:测试档案是否存在

组合条件测试:

当有多个测试条件时,我们可以把这些测试条件组合起来使用:

-a:逻辑与
-o:逻辑或
!:逻辑非,这是单目操作

当是bash命令之间组合测试时,则:
&&:逻辑与
||:逻辑或
!:逻辑非

三、例子

1、写一个脚本来测试一个用户是不是管理员,如果是管理员则显示“用户名 is admin”,如果是系统用户刚显示“用户名 is system user”,否则显示“用户名 is common user”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
#
Uid=`id -u $1 &> /dev/null`
if [ -z $Uid ];then
echo "No such user $1;"
exit 8
fi
if [ $Uid -eq '0' ];then
echo "$1 is admin."
elif [ $Uid -gt '0' -a $Uid -lt '500' ];then //这里用到了逻辑与运算
echo "$1 is system user."
elif [ $Uid -ge '500' ];then
echo "$1 is common user."
fi

2、写一个脚本测试一个用户的shell是不是/bin/bash,如果是那输出“用户名 is bash user.”,否则输出“用户名 is no bash user.”

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
#
Bash=`grep "^$1\>" /etc/passwd | cut -d: -f7`
if [ -z $Bash ];then
echo "No such user $1."
exit 9
fi
if [ $Bash == "/bin/bash" ];then
echo "$1 is bash user."
else
echo "$1 is not bash user."
fi

3、写一个备份脚本,传递参数“gzip,bzip2,xz”给脚本,让脚本调用相应的压缩工具对备份文件进行压缩,当用户没有给定参数时,则调用gzip进行压缩。把/etc目录下的所有文件归档压缩后备份到/backup目录下,备份的文件名为”etc-日期-时间”的形式,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
#
Com=$1
[ -z /backup ] || mkdir /backup &> /dev/null //当无/backup时则建立
if [ -z $Com ];then
Com=gzip
fi
if [ $Com == 'gzip' ];then
tar zcf /backup/etc-`date +%F-%H:%M:%S.tar.gz` /etc/* &> /dev/null
[ $? == 0 ] && echo "Backup etc finished.(gzip)."
elif [ $Com == 'bzip2' ];then
tar jcf /backup/etc-`date +%F-%H:%M:%S.tar.bz2` /etc/* &> /dev/null
[ $? == 0 ] && echo "Backup etc finished.(bz2)."
elif [ $Com == 'xz' ];then
tar Jcf /backup/etc-`date +%F-%H:%M:%S.tar.xz` /etc/* &> /dev/null
[ $? == 0 ] && echo "Backup etc finished.(xz)."
else
echo "Usage:`basename $0` {[gzip|bzip2|xz]}"
exit=7
fi

此脚本在centos5.8上不tar不能调用xz压缩工具进行工作,man tar发现选项里没有“J”选项,但在centos 6.2上能正常工作,应该是tar版本问题。

4 判断上一个语句是否正常执行