三种方式:test , [] , [[]]
其中test和[]等价,[[]]是高级版的[],支持&&、||、<、>等
type [ [[ test
[ isa shell builtin
[[is a shell keyword
testis a shell builtin
可知[[是shell的关键字,[和test是内置命令
例:
test–f file && echo "exist" || echo "doesn't exist"
[-f file ] && echo "exist" || echo "doesn't exist"
[[-f file ]] && echo "exist" || echo "doesn't exist"
等价
touchfile
[! -f file ] && echo "exist" || echo "doesn't exist"
doesn'texist
看看[[]]和[]的区别
[ -f file && -d folder ]&& echo "exist" || echo "doesn't exist"
bash:[: missing `]' #语法错误,提示应该用[[]]
doesn'texist
[[ -f file &&-d folder ]] && echo "exist" || echo "doesn'texist"
doesn't exist
但是[]可以这样实现一次判断多个
[ -f file -a-d folder ] && echo "exist" || echo "doesn't exist"
doesn't exist
如果用[]还非要用&&,可以这样:
[ -f test1.sh ] && [ -x test2.sh] && echo 1 || echo 0
1
test可直接跟表达式
test 2>1 # equal to : [ 2>1 ]
1
文件测试操作符
下面描述测试为真的情况
1.检测文件类型
-e : 文件存在
-f : 文件存在且为普通文件
-d : 文件存在且为目录
-c : 文件存在且为字符设备(character device).键盘,声卡等
-b : 文件存在且为块设备(block device).软盘,光驱等
-p : 文件存在且为FIFO(pipe)文件
-s : 文件存在且不为空(文件大小不为0)
-S : 文件存在且为socket文件
-L : 文件存在且为链接文件
-h : 符号链接,同-L
2.检测文件权限
-r : 文件存在且可读 #这些权限应该是以当前用户身份来判断的
-w : 文件存在且可写
-x : 文件存在且可执行
-u : 文件存在且具有SUID属性
-g : 文件存在且具有SGID属性
-G : FILE exists and is ownedby the effective group ID
-k : 文件存在且具有Sticky属性
-O : FILE exists and is ownedby the effective user ID
3.文件间比较
f1 –nt f2 : 文件f1比f2新
fi –ot f2 : 文件f1比f2旧
f1 –ef f2 : 判断 file1 与 file2 是否为同一文件,可用在判断hard link 的判定上。 主要意义在判定,两个文件是否均指向同一个 inode
4.两个整数间的比较
-eq : 相等
-ne : 不相等
-gt : 大于
-ge: 大于等于
-lt: 小于
-le: 小于等于
这种方式一般在[]中使用,不会出错。在[]中使用<等应该转义。
5.判定字符串
-z: 字符串长度为空为真 (zero)
-n: 字符串长度不为空为真 (not zero)
str1 = str2 : 判定字符串是否相等,与==等价(两端加空格)
str1!= str2 : 判定字符串是否不等
6.多重条件判定
-a: 两种情况同时成立则为真.如 [ -ffile –a –x file ]
-o : 两种情况中任一成立则为真.如 [ -f file –o –x file ]
! : 取非.如 [ ! –x file] 表示若file不具有x权限
另还有:
-t FD : file descriptor FD is opened on a terminal
例:
[ -f "$file" ] && echo 1 || echo 0
if[ -f "$file" ];then echo 1;else echo 0;fi
等价的
变量应该加上双引号,比如下面的例子中,file1变量并不存在
[ -f $file1 ] && echo 1 || echo 0 -> 1(出错了)
但是当直接给定一个不存在文件时
[ -f agc.sh ] && echo 1 || echo 0 -> 0 (又可以断出)
总结:给实际文件可以不加双引号,但是变量一定要加双引号
shell的语法有点乱啊,而且细则太多。反正加上双引号是好习惯
一段nfs脚本
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
[ -f /etc/sysconfig/network ]&& . /etc/sysconfig/network
# Check for and source configuration fileotherwise set defaults
[ -f /etc/sysconfig/nfs ] && ./etc/sysconfig/nfs
# Remote quota server
[ -z "$RQUOTAD" ] &&RQUOTAD=`type -path rpc.rquotad`
比较字符串字符长短
#!/bin/bash
read -p "Please input two chars:"char1 char2
[ "${#char1}" -gt"${#char2}" ] && echo "${char1} is longer than${char2}" || echo "${char1} is shorter than or equal to ${char2}"
(PS:不能判断数字大小:输入1.12 会得到1.1 is longer than 2,因为该脚本比较字符串长度。同时也可以知道,数字加上双引号也可用-gt等比较大小,字符串是不可以用—gt等的)
如果写成
[ "$char1" =="$char2" ]就变成了判断两个字符串是否相同,其实这样也可以判断两个数是否相等
比较数字大小
((2 > 1)) && echo 1 || echo 0
[[ $a1 < $a2 ]] && echo 1 ||echo 0
[ $a1 \< $a2 ] && echo 1 ||echo 0 #注意转义