「test(1)」-

  LINUX MANUAL PAGES

功能简述

检查文件类型及比较值

常用命令

判断文件是否存在:

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逻辑运算符进行测试,而不是内部的这些逻辑运算符。因为使用这些可能会使表达式变得模糊不清。例如:

test “$1” -a “$2”

上面的表达式在$1为!且$2是空字符串时,会变得含糊不清(test “!” -a “”)。应该这么写:

test “$1” && test “$2”

注意,使用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 -eq arg2’


‘arg1 -ne arg2’


‘arg1 -lt arg2’


‘arg1 -le arg2’


‘arg1 -gt arg2’


‘arg1 -ge arg2’

如果arg1与arg2分别相等(eq),不等于(ne),小于(lt),小于等于(le),大于(gt),大于等于(ge),则这些表达式分别返回TRUE。

例如:

# test -1 -gt -2 && echo yes

yes


# test -l abc -gt 1 && echo yes

yes


# test 0x100 -eq 1

error→ test: integer expression expected before -eq

字符串测试

下面这些选项会测试字符串特征。你可能需要为SHELL引用字符串。比如:

test -n “$V”

这里的引号防止错误的参数被传递给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的干扰。下面的命令就是一个很好的例子:

# type -a test

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.

Written by Kevin Braunsdorf and Matthew Bradburn.


# [ –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