功能简述
检查文件类型及比较值
常用命令
判断文件是否存在:
if [ -f /tmp/tmp ] then echo "File exist." fi if test -f /tmp/tmp then echo "File exit." fi
判断目录是否为空:
test -z "$(/bin/ls -A /tmp)" && echo 'empty'
语法格式
test EXPRESSION test [ EXPRESSION ] [ ] [ OPTION
命令描述
命令test会根据EXPRESSION的真与否来返回“0”或“1”。
命令test可以进行文件状态检查,字符串操作,数字比较操作。
命令test有一种替代的形式:使用双方括号。例如,命令test -d /与[ -d / ]是等价的。方括号必须是独立的参数,例如[-d /]是没有任何作用。鉴于二者含义相同,下面只使用其中的一种形式进行讨论。
如果省略EXPRESSION,则test返回false。如果expression是单个参数,则如果参数为null,则test返回false,否则返回true。参数可以是任何字符串,包括像’-d’,’-1’,’–‘,’–help’和’–version’等字符串,大多数其他程序会将其视为选项。要获得帮助和版本信息,可以调用命令'[ –help’和'[ –version’,通常不带右括号。
命令选项
( EXPRESSION )
EXPRESSION为真则返回真。
test命令的连接词
请注意,最好使用SHELL逻辑运算符进行测试,而不是内部的这些逻辑运算符。因为使用这些可能会使表达式变得模糊不清。例如:
上面的表达式在$1为!且$2是空字符串时,会变得含糊不清(test “!” -a “”)。应该这么写:
注意,使用SHELL逻辑运算符可以从短路操作中受益,这对文件属性测试可能很重要。
‘! expr’
如果expr为false,则返回TRUE。‘!’的优先级低于整个expr表达式。
注意,‘!’需要在表达式的左侧。例如,应该使用‘!’ 1 -gt 2,而不是1 ‘!’ -gt 2。并且‘!’是SHELL的特殊字符,最好进行引用。
‘expr1 -a expr2’
当expr1与expr2都为TRUE时,则返回TRUE。’-a’是左关联的,并且具有比’-o’更高的优先级。不建议使用该选项,最好使用SHELL的逻辑运算符。
‘expr1 -o expr2’
当expr1与expr2中有一个为TRUE时,则返回TRUE。’-a’是左关联的。不建议使用该选项,最好使用SHELL的逻辑运算符。
数字比较
数字比较。参数必须完全是数字(可能为负数)。或者是特殊表达式-l string,用于字符串的长度。
‘arg1 -ne arg2’
‘arg1 -lt arg2’
‘arg1 -le arg2’
‘arg1 -gt arg2’
‘arg1 -ge arg2’
如果arg1与arg2分别相等(eq),不等于(ne),小于(lt),小于等于(le),大于(gt),大于等于(ge),则这些表达式分别返回TRUE。
例如:
yes
# test -l abc -gt 1 && echo yes
yes
# test 0x100 -eq 1
error→ test: integer expression expected before -eq
字符串测试
下面这些选项会测试字符串特征。你可能需要为SHELL引用字符串。比如:
这里的引号防止错误的参数被传递给test,比如’$V’为空或者包含特殊字符。
-n STRING
如果字符串的长度不为0,则返回TRUE。
STRING
与-n选项相同。
-z STRING
如果字符串的长度为0,则返回TRUE。
STRING1 = STRING2
如果STRING1与STRING2相同,则返回TRUE。
STRING1 == STRING2
==与=同义。如果STRING1与STRING2相同,则返回TRUE。
STRING1 != STRING2
如果STRING1与STRING2不相同,则返回TRUE。
文件特性测试
-e FILE
文件存在,则返回TRUE。
-s FILE
文件存在并且大小大于0。
FILE1 -ef FILE2
如果FILE1和FILE2具有相同的设备和节点号,则返回TRUE。
FILE1 -nt FILE2
如果FILE1比FILE2新,则返回TRUE。通过文件的修改时间进行比较。
FILE1 -ot FILE2
如果FILE1比FILE2旧,则返回TRUE。通过文件的修改时间进行比较。
访问权限测试
-g FILE
如果文件存在,并且设置了set-group-ID位,则为TRUE。
-u FILE
如果文件存在,并且设置了其set-user-ID位,则为TRUE。
-k FILE
如果文件存在,并设置了粘滞位,则为TRUE。
-r FILE
如果文件存在,并且具有读取权限,则为TRUE。
-w FILE
如果文件存在,并且具有写入权限,则为TRUE。
-x FILE
如果文件存在,并且具有执行权限,则为TRUE。
-G FILE
如果文件存在,并由当前有效组ID拥有,则为TRUE。
-O FILE
如果文件存在,并由当前有效用户ID拥有,则为TRUE。
文件类型测试
-b FILE
如果文件FILE存在并且是块设备,则为TRUE。
-c FILE
如果文件FILE存在并且是字符设备,则为TRUE。
-d FILE
FILE存在,并且是一个目录,则返回TRUE。
-f FILE
FILE存在,并且是一个普通文件,则返回TRUE。
-h FILE
FILE存在,并且是一个符号链接,则返回TRUE。(与-L相同)
-L FILE
FILE存在,并且是一个符号链接,则返回TRUE。(与-h相同)
-p FILE
FILE存在,并且是一个命名管道,则返回TRUE。
-S FILE
文件存在,并且是一个套解字文件,则返回TRUE。
-t FD
FD是一个文件描述符,并且关联到一个终端,则返回TRUE。
除了-h和-L选项之外,文件相关的测试都是针对符号链接指向的文件。
其他选项
–help
显示帮助信息并退出。
–version
显示版本信息并退出。
注意事项
关于SHELL内建的test指令
由于SHELL中可能内置test功能,所有可能会出现与本文中所述的功能不同。通过env(1)调用test命令(即env test …)以避免SHELL的干扰。下面的命令就是一个很好的例子:
test is a shell builtin
test is /usr/bin/test
# type -a [
[ is a shell builtin
[ is /usr/bin/[
# env [ –version
[ (GNU coreutils) 8.26
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
# [ –version
bash: [: missing `]’
# [ –version ]
最后一个命令[ –version ]执行的是SHELL内建的[指令,他不支持–version选项。只有env [ –version执行的[指令才是GNU Coreutils中的[指令。
只有[命令支持–version和–help选项,test命令并不支持。test命令只会将他们视为非空字符串参数。
INTEGER与-l STRING
文档中说“INTEGER may also be -l STRING, which evaluates to the length of STRING.”,但是我们没有找到相关的示例和说明。
附加说明
相关手册
查看在线手册:http://www.gnu.org/software/coreutils/[
查看info手册:info ‘(coreutils) test invocation’
参考文献
man 1 test, version GNU coreutils 8.26
Bash Shell Check Whether a Directory is Empty or Not – nixCraft