一、文件测试
文件测试大多都是单目测试,其用法相对简单,其格式为:
操作符:文件路径
可以用来测试的选项有:
-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风格启动服务时的常用启动格式。