/usr/bin/test [condition]
[ [condition] ]
test [condition]
[ [condition] ]
test [condition]
[ [condition] ]
test [condition]
[ [condition] ]
test [condition]
[ [condition] ]
test 实用程序可评估 condition 并通过其退出状态表明评估结果。退出状态为零表明条件评估为 true,退出状态为 1 表明条件评估为 false。
在“用法概要”部分所示实用程序的第一种格式中:
test [condition]
方括号表示 condition 是可选操作数,不会在命令行中输入。
在“用法概要”部分所示实用程序的第二种格式中:
[ [ condition ] ]
第一个左方括号 [ 是必需的实用程序名称。内部的一对方括号表示 condition 是可选内容。最后一个右方括号 ] 是必需的操作数。
有关 test 遇到大于或等于 2 GB(231 字节)文件时行为的说明,请参见 largefile(5)。
test 和 [ 实用程序将评估条件 condition,如果其值为 true,会将退出状态设置为 0。否则,将设置非零 (false) 退出状态。如果未指定参数,则 test 和 [ 也会设置非零退出状态。测试权限时,将使用进程的有效用户 ID。
所有运算符、标志和括号(括号的用法如“用法概要”部分最后一行所示)必须是这些命令的单独参数。通常,这些参数以空格分隔。
包含两个元素的采用以下格式的基元:
-primary_operator primary_operand
称为一元基元。包含三个元素的采用以下两种格式中任意一种的基元:
primary_operand -primary_operator primary_operand primary_operand primary_operator primary_operand
称为二元基元。
如果除 –h 和 –L 基元之外的任何文件操作数指的是符号链接,则会展开符号链接,并对生成的文件执行测试。
如果测试拥有的文件(–r –w 或 –x 测试),但是测试的权限未设置 owner 位,则即使文件可以设置该权限的 group 或 other 位,也会返回非零 (false) 退出状态。
= 和 != 基元的优先级高于一元基元。= 和 != 基元始终需要参数;因此,= 和 != 不能用作一元基元的参数。
可以使用以下基元构造 condition:
True(如果 file 存在)。(sh 中未提供。)
True(如果 file 存在且为块特殊文件)。
True(如果 file 存在且为字符特殊文件)。
True(如果 file 存在且为目录)。
True(如果 file 存在)。(sh 中未提供。)
True(如果 file 存在且为正规文件)。或者,/usr/bin/sh 用户在 PATH 环境变量中先指定 /usr/ucb 再指定 /usr/bin 时,如果 file 存在且为 (not−a−directory),test 将返回 true。csh test 和 [ 内置命令始终采用这种备用行为。
True(如果 file 存在且设置了其 set-group-ID 标志)。
True(如果 file 存在且其组与该进程的有效组 ID 匹配)。(sh 中未提供。)
True(如果 file 存在且为符号链接)。
True(如果 file 存在且设置了其 sticky 位)。
True(如果 file 存在且为符号链接)。
True(如果 string 的长度为非零值)。
True(如果已启用名为 option 的选项)。csh 和 sh 中未提供该选项。
True(如果 file 存在且归该进程的有效用户 ID 所有)。sh 中未提供该选项。
True(如果 file 是指定管道 (FIFO))。
True(如果 file 存在且可读)。
True(如果 file 存在且其大小大于零)。
True(如果 file 存在且为套接字)。sh 中未提供该选项。
True(如果文件描述符编号为 file_descriptor 的文件已打开且与终端相关联)。如果未指定 file_descriptor,则将 1 用作缺省值。
True(如果 file 存在且设置了其 set-user-ID 标志)。
True(如果 file 存在且可写)。True 只表示启用了写入标志。即使该测试表明 true,file 也无法在只读文件系统上写入。
True(如果 file 存在且可执行)。True 只表示启用了执行标志。如果 file 是目录,true 表示可以搜索 file。
True(如果字符串 string 的长度为零)。
True(如果 file1 存在且比 file2 更新)。sh 中未提供该选项。
True(如果 file1 存在且比 file2 更旧)。sh 中未提供该选项。
True(如果 file1 和 file2 存在且指的是同一文件)。sh 中未提供该选项。
True(如果字符串 string 不是 null 字符串)。
True(如果字符串 string1 和 string2 相同)。
True(如果字符串 string1 和 string2 不同)。
True(如果数字 n1 和 n2 代数值相等)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果数字 n1 和 n2 代数值不等)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果数字 n1 代数值大于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果数字 n1 代数值大于或等于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果数字 n1 代数值小于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果数字 n1 代数值小于或等于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。
True(如果 condition1 和 condition2 均为 true)。–a 二元基元从左向右执行运算,其优先级高于 –o 二元基元。
True(如果 condition1 或 condition2 为 true)。–o 二元基元从左向右执行运算。
这些基元可与以下运算符结合使用:
True(如果 condition 为 false)。
True(如果 condition 为 true)。可以使用括号 ( ) 更改常规优先级和结合性。括号对 shell 有意义,因此必须用引号引起来。
确定运算符优先级的算法和生成的返回值基于提供给 test 的参数的数目。(但是,采用 [...] 格式时,右括号的最后一个参数并不计入这种算法。)
在以下列表中,$1、$2、$3 和 $4 表示作为 condition、condition1 或 condition2 提供给 test 的参数。
退出值为 false (1)。
退出值为 true (0)(如果 $1 不为空)。否则,退出值为 false。
$1 为 ! 时,如果 $2 为空,退出值为 true;如果 $2 不为空,退出值为 false。
$1 为一元基元时,如果一元测试为 true,退出值为 true;如果一元测试为 false,退出值为 false。
否则,不会产生指定的结果。
如果 $2 为二元基元,将执行 $1 和 $3 的二元测试。
如果 $1 为 !,将否定 $2 和 $3 的两个参数的测试。
否则,不会产生指定的结果。
如果 $1 为 !,将否定 $2、$3 和 $4 的三个参数的测试。
否则,结果不确定。
处理用户提供的输入时,使用脚本应该非常小心,因为输入可能与基元和运算符混淆。除非应用程序编写者了解在脚本中生成输入的所有情况,否则诸如 test "$1" -a "$2" 之类的调用应写为 test "$1" && test "$2",以避免由用户提供值(例如将 $1 设置为 !,将 $2 设置为空字符串)时出现问题。也就是说,如果最高可移植性关系重大,应将 test expr1 -a expr2 替换为 test expr1 && test expr2,将 test expr1 -o expr2 替换为 test expr1 || test expr2。但请注意,在 test 中,–a 优先级高于 –o,而在 shell 中,&& 和 || 优先级相等。
在 shell 命令语言中,可使用圆括号或花括号来影响分组。
使用 sh 时,圆括号必须进行转义。例如:
test \( expr1 -a expr2 \) -o expr3
该命令并不总是能够移植到符合 XSI 要求的系统以外。在这种情况下,可采用以下格式:
( test expr1 && test expr2 ) || test expr3
以下两个命令:
test "$1" test ! "$1"
在以前的某些系统上无法可靠地使用。如果使用了此类 string 条件且 $1 扩展到 !、( 或已知的一元基元,会产生异常结果。更好的结构分别是:
test -n "$1" test -z "$1"
以前的系统采用以下通用结构,这也导致了不可靠:
test "$response" = "expected string"
以下结构更为可靠:
test "X$response" = "Xexpected string" test "expected string" = "$response"
第二种格式假定 expected string 不能与任何一元基元混淆。如果 expected string 以 −、(、! 或 = 开头,应采用第一种格式。无论输入为何,只要在不带标记扩展的情况下采用前面的规则,这三种比较格式都非常可靠。(但请注意,字符串在所有情况下均用引号引起来。)
由于字符串比较二元基元 = 和 != 优先级高于参数超过 4 个时的任何一元基元,因此如果未妥善准备参数,可能会产生异常结果。例如,在以下命令中:
test -d $1 -o -d $2
如果 $1 评估结果为 = 可能的目录名称,将前三个参数视为字符串比较,这会导致遇到第二个 –d 时出现语法错误。以下格式可以防止该问题,首选第二种:
test \( -d "$1" \) -o \( -d "$2" \) test -d "$1" || test -d "$2"
同样,参数超过 4 个时:
test "$1" = "bat" -a "$2" = "ball"
如果 $1 评估结果为 ( 或 !,则会出现语法错误。以下格式可以防止该问题,首选第三种:
test "X$1" = "Xbat" -a "X$2" = "Xball" test "$1" = "bat" && test "$2" = "ball" test "X$1" = "Xbat" && test "X$2" = "Xball"
在 if 命令示例中,测试了三个条件,如果三个全部评估为 true 或成功,则会将其有效性写入屏幕。这三项测试包括:
设置为 1 的变量是否大于 0
设置为 2 的变量是否等于 2
文本文件 /etc/passwd 中是否包含 root 一词
如果目录不存在,执行 mkdir:
test ! -d tempdir && mkdir tempdir
等到文件变为不可读时:
while test -r thefile do sleep 30 done echo'"thefile" is no longer readable'
如果参数是以下三个字符串(两种变体)之一,执行命令,使用左方括号版本 [ 的 test 命令执行命令:
if [ "$1" = "pear" ] || [ "$1" = "grape" ] || [ "$1" = "apple" ] then command fi case "$1" in pear|grape|apple) command;; esac示例 2 将 /usr/bin/test 用于 -e 选项
如果确实希望在 sh 中使用 –e 选项,应按如下方式使用 /usr/bin/test:
if [ ! -h $PKG_INSTALL_ROOT$rLink ] && /usr/bin/test -e $PKG_INSTALL_ROOT/usr/bin/$rFile ; then ln -s $rFile $PKG_INSTALL_ROOT$rLink fi
test 内置命令的两种格式遵循 Bourne shell 的 if 示例。
示例 3 使用 sh 内置命令ZERO=0 ONE=1 TWO=2 ROOT=root if [ $ONE –gt $ZERO ] [ $TWO –eq 2 ] grep $ROOT /etc/passwd >&1 > /dev/null # discard output then echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \ "a user-name in the password file" else echo "At least one of the three test conditions is false" fi示例 4 使用 test 内置命令
test 内置命令示例如下:
test `grep $ROOT /etc/passwd >&1 /dev/null` # discard output echo $? # test for success [ `grep nosuchname /etc/passwd >&1 /dev/null` ] echo $? # test for failure
@ ZERO = 0; @ ONE = 1; @ TWO = 2; set ROOT = root grep $ROOT /etc/passwd >&1 /dev/null # discard output # $status must be tested for immediately following grep if ( "$status" == "0" && $ONE > $ZERO && $TWO == 2 ) then echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \ "a user-name in the password file" endif
ZERO=0 ONE=1 TWO=$((ONE+ONE)) ROOT=root if ((ONE > ZERO)) # arithmetical comparison [[ $TWO = 2 ]] # string comparison [ `grep $ROOT /etc/passwd >&1 /dev/null` ] # discard output then echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \ "a user-name in the password file" else echo "At least one of the three test conditions is false" fi
有关影响 test 执行的环境变量 LANG、LC_ALL、LC_CTYPE、LC_MESSAGES 和 NLSPATH 的说明,请参见 environ(5)。
将返回以下退出值:
condition 评估结果为 true。
condition 评估结果为 false 或缺少 condition。
出现错误。
有关下列属性的说明,请参见 attributes(5):
|
|
csh(1)、ksh(1)、ksh88(1)、sh(1)、test(1B)、attributes(5)、environ(5)、largefile(5)、standards(5)
not−a−directory 可以替代 –f 选项,但它只是在过渡期间对 BSD 应用程序起帮助作用,在未来的发行版中可能不再受支持。
使用算术表达式,例如
$(( x > 3.1 )) #
而非
$ /usr/bin/test "$x" -gt 3.1 # )
-在比较两个浮点变量或一个常量和一个浮点变量以防止舍入误差(由 base16 到 base10 的转换造成)影响结果时。此外,XPG4 sh、ksh88 和 ksh 中支持的内置命令算术速度明显加快,因为无需对每项比较的字符串进行显式转换。