test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。

test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测

Shell test 命令的用法为:

test expression

当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。test 命令也可以简写为​​[](​​​test 和 [] 是等价的​​)​​,它的用法为:

[ expression ]

注意​​[]​​​和​​expression​​​之间的空格,这两个空格是必须的,否则会导致语法错误。​​[]​​的写法更加简洁,比 test 使用频率高。

 

1) 与文件检测相关的 test 选项


表1:test 文件检测相关选项列表

文件类型判断

选 项

作 用

-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 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

[root@www ~]# test -d /tmp && echo "/tmp dir exit"
/tmp dir exit
[root@www ~]# test -d /tm && echo "/tmp dir exit"
[root@www ~]#


#nginx make install
test -d '/usr/local/nginx/' || mkdir -p '/usr/local/nginx/'

test ! -f '/usr/local/nginx//sbin/nginx' \
|| mv '/usr/local/nginx//sbin/nginx' \
'/usr/local/nginx//sbin/nginx.old'
cp objs/nginx '/usr/local/nginx//sbin/nginx'


判断目录是否存在
#!/bin/bash
path="/home"
#if [ ! -d ${path} ];then
if [ -d ${path} ];then
echo dir ${path} exist!
else
echo dir ${path} not exist!
fi

 

2) 与数值比较相关的 test 选项


表2:test 数值比较相关选项列表

选 项

作 用

num1 -eq num2

判断 num1 是否和 num2 相等。

num1 -ne num2

判断 num1 是否和 num2 不相等。

num1 -gt num2

判断 num1 是否大于 num2 。

num1 -lt num2

判断 num1 是否小于 num2。

num1 -ge num2

判断 num1 是否大于等于 num2。

num1 -le num2

判断 num1 是否小于等于 num2。

注意,test 只能用来比较整数,小数相关的比较还得依赖 ​​bc 命令​​。Shell test 数值比较举例:

#!/bin/bash
read a b

if test $a -eq $b
then
echo "两个数相等"
else
echo "两个数不相等"
fi


#!/bin/bash
if [ 2 -eq 3 ];then
echo 'equal'
else
echo 'not equal'
fi

Q:7 在shell脚本中如何比较两个数字 ?  --面试题

答:在if-then中使用测试命令( -gt 等)来比较两个数字,例子如下:

#!/bin/bash
x=10
y=20
if [ $x -gt $y ]
then
echo “x is greater than y”
else
echo “y is greater than x”
fi

 

3) 与字符串判断相关的 test 选项


表3:test 字符串判断相关选项列表

选 项

作 用

-z str

判断字符串 str 是否为空。

-n str

判断宇符串 str 是否为非空。

str1 = str2

str1 == str2

​=​​​和​​==​​是等价的,都用来判断 str1 是否和 str2 相等。

str1 != str2

判断 str1 是否和 str2 不相等。

str1 \> str2

判断 str1 是否大于 str2。​​\>​​​是​​>​​​的转义字符,这样写是为了防止​​>​​被误认为成重定向运算符。

str1 \< str2

判断 str1 是否小于 str2。同样,​​\<​​也是转义字符。

有C语言、​​C++​​​、​​Python​​​、​​Java​​ 等编程经验的读者请注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的,大家要习惯。其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记。

Shell test 字符串比较举例:

#!/bin/bash
read str1
read str2
#检测字符串是否为空
if [ -z "$str1" ] || [ -z "$str2" ]
then
echo "字符串不能为空"
exit 0
fi


#比较字符串
#!/bin/bash
if [ $str1 = $str2 ]
then
echo "两个字符串相等"
else
echo "两个字符串不相等"
fi



#!/bin/bash
read str1
if [ "$str1" == "test" ];then
echo "equal test"
else
echo "not equal test"

fi
[root@www ~]# ./test.sh
test
equal test
[root@www ~]# ./test.sh
myets
not equal test

变量 $str1 和 $str2 都被双引号包围起来,这样做是为了防止 $str1 或者 $str2 是空字符串时出现错误(最好的字符串比较写法是[ -z "$变量" ]这种写法,要不会报错如:./env.sh: line 8: [: too many arguments)

 

Q:16 shell脚本如何比较字符串?  --面试题

答:test命令可以用来比较字符串。测试命令会通过比较字符串中的每一个字符来比较。