test语句的用法
test是Shell内置命令,用来检测某个条件是否成立。
test通常和if语句- -起使用,并且大部分if语句都依赖test
test命令有很多选项,可以进行数值、字符串和文件三个方面的检测。
Shell test命令的用法为: test expression
当test判断expression成立时,退出状态为0,否则
为非0值
test命令也可以简写为[],它的用法为: [ expression ]
#注意[]和expression之间的空格,这两个空格是必须
的,否则会导致语法错误。[]的写法更加简洁,比test使用频率高
test的数值比较
参数 | 说明 |
---|---|
-eq | 等于则为真 |
-ne | 不等于则为真 |
-gt | 大于则为真 |
-ge | 大于等于则为真 |
-lt | 小于则为真 |
-le | 小于等于则为真 |
例:
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
输出结果:两个数相等
#!/bin/bash
a=5
b=6
result=$[a+b] # 注意等号两边不能有空格
echo "result 为: $result"
输出结果:11
字符串比较
参数 | 说明 |
---|---|
str1 = str2 | 检查str1是否和str2相同 |
str1!= str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 |
-Z str1 | 检查str1的长度是否为0 |
例:
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
输出结果:两个字符串相等!
有C语言、C++、Python、Java 等编程经验的读者请注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的,大家要习惯
其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记
文件比较
文件类型判断
参数 | 说明 |
---|---|
-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 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
输出结果:文件已存在!
另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!“最高,”-a"次之,"-o"最低。例如:
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
输出结果:至少有一个文件存在!
test总结
在test 中使用变量建议用双引号包围起来
- test和[]都是命令,一个命令本质上对应一个程序或者一个函数。即使是一个程序,它也有入口函数,例如C语言程序的入口函数是main(), 运行C语言程序就从main() 函数开始,所以也可以将一个程序等效为一个函数,这样我们就不用再区分函数和程序了,直接将一个命令和一个函数对应起来即可。
有了以上认知,就很容易看透命令的本质了:使用一个命令其实就是调用一 个函数,命令后面附带的选项和参数最终都会作为实参传递给函数。
假设test命令对应的函数是func(),使用test -z $ str1命令时,会先将变量$ str1替换成字符串:
- 如果 $ str1是一个正常的字符串,比如abc123, 那么替换后的效果就是test -z abc123, 调用func() 函数的形式就是func("-z abc123")。 test命令后面附带的所有选项和参数会被看成一个整体,并作为实参传递进函数。
- 如果$ str1是一个空字符串,那么替换后的效果就是test -Z,调用func() 函数的形式就是func("-z "), 这就比较奇怪了,因为-z选项没有和参数成对出现,func() 在分析时就会出错。
- 如果我们给$ str1变量加上双引号,当 s t r 1 是 空 字 符 串 时 , t e s t − Z " str1 是空字符串时,test -Z " str1是空字符串时,test−Z"str1 “就会被替换为test -Z“", 调用func() 函数的形式就是func("-z “”"), 很显然,-z选项后面跟的是一个空字符串("表示转义字符),这样func() 在分析时就不会出错了
总结:
- test命令比较奇葩,>、<、==只能用来比较字符串,不能用来比较数字,比较数字需要使用-eq、 -gt等选项;不管是比较字符串还是数字,test 都不支持>=和<=。有经验的程序员需要慢慢习惯test 命令的这些奇葩用法。
- 对于整型数字的比较,我建议大家使用(()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便
注意:
test命令使用标准的数学比较符号来表示字符串比较
而用文本代码来表示数值比较这个细微的特性会被很多程序员理解反了
如果你为数值使用了数学运算符shell会将他们当成字符串可以无法产生正确的结果