1.条件测试常用的几种用法
语法 | 说明 |
---|---|
test <表达式> | 使用test命令进行条件测试 |
[ <表达式> ] | 通过中括号进行条件测试,中括号与表达式边界有空格 |
[[<表达式>]] | 通过双括号进行条件测试,表达式与空括号边界有空格 |
((<表达式>)) | 双小括号进行条件测试 |
2、条件测试与文件相关的选项
文件类型判断
选项 | 作用 |
---|---|
-b filename | 判断文件是否存在,并且是否为块设备文件。 |
-c filename | 判断文件是否存在,并且是否为字符设备文件。 |
-d filename | 判断文件是否存在,并且是否为目录文件。 |
-e filename | 判断文件是否存在。存在即为真 |
-f filename | 判断文件是否存在,井且是否为普通文件。 |
-L filename | 判断文件是否存在,并且是否为符号链接文件。 |
-p filename | 判断文件是否存在,并且是否为管道文件。 |
-s filename | 判断文件是否存在,并且是否为非空。 |
-S filename | 判断该文件是否存在,并且是否为套接字文件。 |
文件权限判断
选项 | 作用 |
---|---|
-r filename | 判断文件是否存在,并且是否拥有读权限。 |
-w filename | 判断文件是否存在,并且是否拥有写权限。 |
-x filename | 判断文件是否存在,并且是否拥有执行权限。 |
-u filename | 判断文件是否存在,并且是否拥有 SUID 权限。 |
-g filename | 判断文件是否存在,并且是否拥有 SGID 权限。 |
-k filename | 判断该文件是否存在,并且是否拥有 SBIT 权限。 |
文件比较
选项 | 作用 |
---|---|
filename1 -nt filename2 | 判断 filename1 的修改时间是否比 filename2 的新。 |
filename -ot filename2 | 判断 filename1 的修改时间是否比 filename2 的旧。 |
filename1 -ef filename2 | 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
说明以下几点:
1、test和[]的作用是等价的
2、[[]]为扩展的test,是一种新的用法
3、(())常用于计算,很少用于条件测试判断
4、常用的&&、||、<、>等操作符,只可以用在[[]]中,在[]中常用-a、-o、-gt、-lt作为操作符(gt和lt等比较大小的操作符用于整数)
3、test条件测试实例
#通过-f选项判断file是否为普通文件,如果是,则返回yes,如果不是返回no;如果文件不存在,同样视为假,即返回no
~]# test -f file && echo yes || echo no
no
4、[]条件测试实例
#与test功能完全一样,都是判断file文件是否为普通文件,是返回yes,不是返回no,如果文件不存在,同样视为假,即返回no
~]# [ -f file ] && echo yes || echo no
no
#测试file文件存在且为普通文件
~]# touch file
~]# [ -f file ] && echo yes || echo no
yes
5、[[]]条件测试实例
判断file文件是否为普通文件,是返回yes,不是返回no,如果文件不存在,同样视为假,即返回no
~]# [[ -f file ]] && echo yes || echo no
yes
双中括号用法和选项部分与test是相同的,不同的地方在于,双中括号支持通配符等进行模式匹配,并且支持&&、||等操作符;
6、常用的条件测试选项应用
1、测试文件是否为目录
[ -d dir ] && echo yes || echo no
2、测试文件属性
-rw-r--r-- 1 root root 0 11月 19 08:42 file
[ -r file ] && echo yes || echo no
[ -w file ] && echo yes || echo no
[ -x file ] && echo yes || echo no
注意:如果是root用户操作,即使属主和属组以及其他人都没有读写权限,执行判断文件是否有读写权限,得到的结果是yes,这是root用户比较特殊的地方
3、变量条件判断
[ -f "$a" ] && echo yes || echo no
注意:使用中括号进行变量测试判断时,变量必须加双引号,否则会有问题
7、特殊的条件测试方法
此方法一般是替代if语句进行条件测试的方法,判断条件成立或者不成立,进而执行多条命令,格式如下
[ 条件 ] &&{
命令1
命令2
}
上述效果等同if语句效果
if [ 条件 ]
then
命令1
命令2
fi
实例演示
1、如果/etc文件不是普通文件,则输出3行数字
#!/bin/bash
[ -f /etc ] || {
echo 1
echo 2
echo 3
}
如果要在命令提示符下一行执行,则大括号与输出内容两端有空格,并且里面的命令分号分隔
~]# [ -f /etc ] || { echo 1;echo 2; echo 3; }
8、字符串测试操作符
字符串 | 说明 |
---|---|
n “字符串” | 如果字符串的长度不为0,则为真 |
-z “字符串” | 如果字符串长度为0,则为真 |
“字符串1” = “字符串2” | 如果字符串1等于字符串2,则为真 |
“字符串1” != “字符串2” | 如果字符串1不等于字符串2,则为真 |
注意:针对字符串测试,一定要将字符串加双引号
比较符号两端一定要有空格
1、如果字符串长度不为0,则输出yes
[ -n "shanghai" ] && echo yes
2、如果字符串长度为0,输出yes
[ -z "$a" ] && echo yes
3、如果变量a和变量b相同,则输出yes
[ "$a" = "$b" ] && echo yes
#注意等号两端与变量之间有空格,否则在变量不同是,出现逻辑错误
4、如果变量a和变量b不相同,则输出yes
[ "$a" != "$b" ] && echo yes
9、条件测试操作符的使用说明
在test和[]中使用的比较符号 | 在(())和[[]]中使用的比较符号 | 说明 |
---|---|---|
-eq | ==或者= | 相等 |
-ne | != | 不相等 |
-gt | > | 大于 |
-ge | >= | 大于等于 |
-lt | < | 小于 |
-le | <= | 小于等于 |
1、以上说明整理仅仅表示相对而言,是比较好的对应选择关系
2、=和!=也可以在[]中使用,<和>比较符号同样也可以,但是需要转义
3、-gt和-lt同样也可以在[[]]中使用
4、操作符两端要与字符串有空格
10、逻辑操作符说明
在test和[]中使用的比较符号 | 在(())和[[]]中使用的比较符号 | 说明 |
---|---|---|
-a | && | and,与,两端都为真,结果真 |
-o | || | or,或,两端有一个为真,结果真 |
! | ! | not,非,两端结果相反,取反 |
1、在中括号中,不能使用&&、||;语法错误
2、在[[]]和(())中使用-a或者-o,会出现语法错误
实例:输入一个字符或者数字,如果输入的是数字1,则输出数字1,如果是数字2,则输出2,如果不是1或者2,则提示输入错误,然后退出程序
#!/bin/bash
read -t 10 -p "please input one number:" num1 #read读取一个数字
[ -z "$num1" ] && {
echo "please input number again!" #判断数字是否为空
exit 1
}
expr $num1 + 1 &>/dev/null #判断数字是否为整数
RE=$?
test $RE -eq 0 ||{
echo "input number!"
exit 1
}
[ "$num1" = 1 ] && { #如果输入数字为1,则输出1
echo 1
exit 1
}
[ "$num1" = 2 ] && { #如果输入数字为2,则输出2
echo 2
exit 1
}
[ "$num1" != 1 -a "$num1" != 2 ] && { #如果既不是1也不是2,则输出错误,退出程序
echo "input errro"
exit 1
}
实例:开发两个脚本,一个通过read方式读取两个数,进行比较两个整数的大小,并将结果输出给用户,不使用if,另一个脚本通过传参的方式开发,要求确定变量个数和是否为数字
#!/bin/bash
read -t 10 -p "please input two numbers:" num1 num2 #read读取两个数字
[ -z $num1 ] && [ -z $num2 ] && {
echo please input number again! #判断两个数字是否为空
exit 1
}
expr $num1 + $num2 + 1 &>/dev/null #判断两个变量是否位数字
RE=$?
[ $RE = 0 ] || {
echo please input number!
exit 1
}
[ $num1 -lt $num2 ] && {
echo "$num1 < $num2" #此处开始比较大小
exit 1
}
[ $num1 -gt $num2 ] && {
echo "$num1 > $num2"
exit 1
}
[ $num1 -eq $num2 ] && {
echo "$num1 = $num2"
exit
}
#!/bin/bash
[ $# = 2 ] || {
echo "usage:$0 num1 num2" #判断参数个数是否为2个
exit 0
}
a=$1 #传递参数1
b=$2 #传递参数2
expr $a + $b + 1 &>/dev/null
RE=$?
[ $RE = 0 ] || {
echo Input erro,please input number! #判断是否为数字
exit 0
}
[ $a -lt $b ] && { #此处开始比较数字大小,并输出结果
echo "$a < $b"
exit 0
}
[ $a -gt $b ] && {
echo "$a > $b"
exit 0
}
[ $a = $b ] && {
echo "$a = $b"
exit 0
}
实例:创建一个菜单脚本,可供用户选择一键安装LAMP或者LNMP
#!/bin/bash
path=/user/scripts #指定lamp和lnmp安装脚本的路径
[ ! -d $path ] && mkdir -p $path #目录是否存在,不存在直接创建
cat <<EOT
1.[install LAMP] #设置选择菜单
2.[install LNMP]
3.[exit]
EOT
read -p "please change menu:" num #read读取用户输入选择
expr $num + 1 &>/dev/null
[ $? = 0 ] || {
echo "You need input numbers:{1|2|3}" #判断是否输入的数字
exit 0
}
[ $num = 1 ] && {
echo "starting install LAMP!" #如果选择1,则安装lamp
sleep 5
[ -x $path/lamp.sh ] || {
echo "This is not an executable file!" #判断脚本目录下的lamp是否为可执行文件
exit 0
}
source $path/lamp.sh #执行脚本
exit $?
}
[ $num = 2 ] && {
echo "starting install LNMP!" #如果选择2,则安装lnmp
sleep 5
[ -x $path/lnmp.sh ] || {
echo "This is not an executable file" #判断脚本目录下的lnmp是否为可执行文件
exit 0
}
source $path/lnmp.sh #执行脚本
exit $?
}
[ $num = 3 ] && {
echo bye bye #如果选择3,则退出当前脚本,不执行任何操作
exit 0
}
[[ $num != [1-3] ]] && {
echo "You need input numbers:{1|2|3}" #如果选择的不是菜单内的三个选项数字,则输出错误,退出
exit 0
}
11、总结
表达式符号 | [] | test | [[]] | (()) |
---|---|---|---|---|
边界是否需要空格 | 需要 | 需要 | 需要 | 不需要 |
逻辑操作符 | !、-a、-o | !、-a、o | !、&&、|| | !、&&、|| |
整数比较操作符 | -eq、-lt、-gt、-ge、-le | -eq、-lt、-gt、-ge、-le | =、>、<、>=、<=或者-eq、-lt、-gt、-ge、-le = | =、>、<、>=、<= |
字符串比较操作符 | =、==、!= | =、==、!= | =、==、!= | =、==、!= |
是否支持通配符 | 不支持 | 不支持 | 支持 | 不支持 |