您的位置:首页 > 运维架构 > Shell

26_Shell语言――――if条件判断之文件测试、短路操作符

2014-07-25 22:29 621 查看
一、文件测试
文件测试大多都是单目测试,其用法相对简单,其格式为:
操作符:文件路径可以用来测试的选项有:
-f:测试其是否为普通文件,即使用ls -l命令查看时,文件类型显示为 - 的文件;-d:测试其是否为目录文件,即使用ls -l命令查看时,文件类型显示为 d的文件;-e:测试文件是否存在,不论是目录还是文件,如果存在则为真,否则为假;-r:测试文件对当前访问者来说(非创建者)是否可读;-w:测试文件对当前访问者来说(非创建者)是否可写;-x:测试文件对当前访问者来说(非创建者)是否可执行;-s:测试文件是否有大小,如果有大小则为真,否则为假;-l:测试文件是否为链接文件 例如要检验/tmp/test10是否不存在,如果不存在就创建之:
[root@localhost~]# vim if_exist.sh
#!/bin/bash
#
if [ ! -e /tmp/test10 ]; then
#测试文件不存在,故对文件存在的情况取反
mkdir /tmp/test10
fi
[root@localhost~]# bash -x if_exist.sh
+ '[' '!' -e /tmp/test10 ']'
+ mkdir /tmp/test10
[root@localhost~]# ls /tmp
a.sh  d.sh keyring-bgxXAq  orbit-gdm           pulse-yCmeAwocSW1U   virtual-root.plTHoO  yum.log
b.sh  e.sh keyring-Xi9NCS  orbit-root          test10               virtual-root.q9Sgpu
c.sh  f.sh keyring-xva5ss pulse-uP5T8Y6V6nIN virtual-root.nBhtJw virtual-root.rQ0Eab
#test10这个目录已经创建了。

二、短路操作符
上面测试 /tmp/test10是否存在的例子,其实可以写作更简单的形式:[-e /tmp/test10 ] || mkdir /tmp/test10这里的 || 就是短路操作符,意为或运算,即先测试|| 前面的语句,如果为真,就不测试 || 后面的语句了;如果|| 前面的语句为假,则继续测试 || 后面的语句。短路操作符主要有以下几种:&&: 与运算, 与运算的情况有:真 && 真 = 真真 && 假 = 假假 && 真 = 假 假 && 假 = 假 ||: 或运算,或运算的情况有:真 || 真 = 真假 || 真 = 真真 || 假 = 真假 || 假 = 假注意,与运算具有优先级,即与运算先操作,或运算后操作 如果某个用户不存在,就创建该用户的例子,也可以用这种方式写:
id $UserName&> /dev/null || useradd $UserName
现在把这个例子复杂化:使用与运算和或运算的形式,测试一个用户是否存在,如果存在就显示其以存在,否则就创建这个用户[root@localhosttutor]# vim if_user6.sh
#1/bin/bash

UserName=$1
! id $UserName&> /dev/null && useradd $UserName || echo "$UserNameexists."
#如果用户存在,则 && 前的部分为假,那么需要判断&& 后面的部分;
#如果用户不存在,则 &&前面的部分为真,那么不需要判断&& 后面的部分
#对于 || 运算来说,如果用户不存在,则前半部分都为假,则需要运行 || 后面的部分

[root@localhosttutor]# bash -x if_user6.sh root
+UserName=root
+ id root
+ echo 'rootexists.'
root exists.
[root@localhosttutor]# bash -x if_user6.sh roott
+ UserName=roott
+ id roott
+ useraddroott
三、文件测试及短路运算综合实例例1. 给定一个路径,判断如果为普通文件,显示之;如果为目录,显示之;否则显示为无法识别[root@localhost tutor]# vim if_file.sh
#!/bin/bash
#

if [ ! -e $1]; then
echo "No such file."
exit 7
fi
# 先判断文件是否存在
if [ -f $1 ];then
echo "Common file."
elif [ -d $1]; then
echo "Directory."
else
echo "Unknown file."
fi
[root@localhost tutor]# bash if_file.sh /tmp
Directory.
[root@localhost tutor]# bash if_file.sh /etc
Directory.
[root@localhost tutor]# bash if_file.sh /etc/fstab
Common file.
[root@localhost tutor]# bash if_file.sh /etc/fstabb
No such file.
[root@localhost tutor]# bash if_file.sh /dev/sda
Unknown file.
例2. 写一个脚本,判断/var/log目录中所有文件的类型[root@localhost tutor]# vim file_type.sh
#!/bin/bash
#

for File in/var/log/*; do
if [ -f $File ]; then
echo "$File: Commonfile."
elif [ -d $File ]; then
echo "$File:Directory."
else
echo "$File: Unknownfile."
fi
done
[root@localhost tutor]# bash file_type.sh
/var/log/anaconda.yum.log:Common file.
/var/log/audit:Directory.
/var/log/boot.log:Common file.
/var/log/ConsoleKit:Directory.
例3. 写一个脚本:可以接受一个参数,其使用形式如下: script.sh {start|stop|restart|status}如果参数为start,创建空文件/var/lock/subsys/script,并显示“Starting scriptsuccessfully.”;如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;如果参数为restart,则删除文件/var/lock/subsys/script后重新创建,并显示“Restarting scriptsuccessfully.”;如果参数为status,那么:如果/var/lock/subsys/script文件存在,则显示为“script is running.否则,则显示为“script is stopped.其它任何参数:则显示“script.sh{start|stop|restart|status}这里稍微补充一下,$0为脚本自身的名称,但是引用$0时,会引用全路径及名称,故如果只想引用脚本本身的名称,可以使用basename $0。[root@localhost tutor]# vim service.sh――――――――――――――以下为脚本内容――――――――――――――――――
#!/bin/bash
#

SvcName=`basename$0`
# 使用basename取该脚本的基名
LockFile="/var/lock/subsys/$SvcName"
# 提供一个锁文件的路径

if [ $# -lt 1]; then
# 判断参数个数是否少于1,是则给用户提示信息,并退出脚本
echo "Usage: $SvcName {start |stop | restart | status}"
exit 3
fi

if [ $1 =='start' ]; then

if [ -e $LockFile ]; then
# 先判断该文件是否存在,如果存在,则不创建
echo "$SvcName isrunning."
else
touch $LockFile &>/dev/null
# 如果参数为start,且文件不存在,则创建该文件
echo "Starting $SvcNamesuccessfully."
fi

elif [ $1 =='stop' ]; then

if [ -e $LockFile ]; then
# 如果传递的参数是stop,则先判断文件是否存在,如果存在就删除该文件
rm -f $LockFile &>/dev/null
echo "Stopping $SvcNamefinished."
else
# 如果文件不存在,则无需删除,给出提示信息即可
echo "$SvcName is stoppedyet."
fi

elif [ $1 =='restart' ]; then
rm -f $LockFile &> /dev/null
touch $LockFile &> /dev/null
# 如果参数为restart,则先删除该文件,再创建之
echo "Restarting $SvcNamesuccessfully."
elif [ $1 =='status' ]; then
# 如果参数为status,那么需要用到嵌套语句,考虑文件是否存在
if [ -e $LockFile ]; then
echo "$SvcName isrunning."
else
echo "$SvcName isstopped."
fi
else
echo "Usage: $SvcName {start |stop | restart | status}"
exit 4
# 如果输入的参数不是这4个中的一个,给用户提示信息,并退出,且错误编号与无参数的情况不同
fi
――――――――――――――下面来测试该脚本―――――――――――――――――― [root@localhost tutor]# chmod +x service.sh[root@localhost tutor]# ./service.sh
Usage:service.sh {start | stop | restart | status}
[root@localhost tutor]# echo $?
3
[root@localhost tutor]# ./service.sh start
Starting service.sh successfully.
[root@localhost tutor]# ls /var/lock/subsys
abrt-ccpp  atd    blk-availability  cups       local         network         pcscd    rpc.statd  sshd
abrtd      auditd certmonger        haldaemon  lvm2-monitor NetworkManager  postfix  rsyslog
acpid      autofs crond             ip6tables  messagebus   openct          rpcbind  service.sh
# 可以看到/var/lock/subsys下成功创建了service.sh文件

[root@localhost tutor]# ./service.sh stop
Stopping service.sh finished.
[root@localhost tutor]# ls /var/lock/subsys
abrt-ccpp  atd    blk-availability  cups       local         network         pcscd    rpc.statd
abrtd      auditd certmonger        haldaemon  lvm2-monitor NetworkManager  postfix  rsyslog
acpid      autofs crond             ip6tables  messagebus   openct          rpcbind  sshd
# 传递的参数为stop,则强行删除了 service.sh文件

[root@localhost tutor]# ./service.sh restart
Restarting service.sh successfully.
[root@localhost tutor]# ls /var/lock/subsys
abrt-ccpp  atd    blk-availability  cups       local         network         pcscd    rpc.statd  sshd
abrtd      auditd certmonger        haldaemon  lvm2-monitor NetworkManager  postfix  rsyslog
acpid      autofs crond             ip6tables messagebus    openct          rpcbind  service.sh
# 传递的参数为restart,强行删除了 service.sh文件后又创建了一遍

[root@localhost tutor]# ./service.sh status
service.sh isrunning.
# 传递的参数为status,则显示当前文件存在与否

[root@localhost tutor]# ./service.sh stop
Stopping service.shfinished.
[root@localhost tutor]# ./service.sh status
service.sh isstopped.
[root@localhost tutor]# ./service.sh stat
Usage:service.sh {start | stop | restart | status}
# 传递错误参数,给予提示信息后退出

[root@localhost tutor]# ./service.sh start
Startingservice.sh successfully.
[root@localhost tutor]# ./service.sh start
service.sh isrunning.
# 文件已经存在了

[root@localhost tutor]# ./service.sh stop
Stoppingservice.sh finished.
[root@localhost tutor]# ./service.sh stop
service.sh isstopped yet.
# 文件不存在

上述脚本是红帽系统遵循SysV风格启动服务时的常用启动格式

本文出自 “重剑无锋 大巧不工” 博客,请务必保留此出处http://wuyelan.blog.51cto.com/6118147/1530284
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: