手册页部分 1: 用户命令

退出打印视图

更新时间: 2014 年 7 月
 
 

test(1)

名称

test - 评估条件

用法概要

/usr/bin/test [condition]
[ [condition] ]

sh

test [condition]
[ [condition] ]

csh

test [condition]
[ [condition] ]

ksh88

test [condition]
[ [condition] ]

ksh

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 位,则即使文件可以设置该权限的 groupother 位,也会返回非零 (false) 退出状态。

=!= 基元的优先级高于一元基元。=!= 基元始终需要参数;因此,=!= 不能用作一元基元的参数。

可以使用以下基元构造 condition

–a file

True(如果 file 存在)。(sh 中未提供。)

–b file

True(如果 file 存在且为块特殊文件)。

–c file

True(如果 file 存在且为字符特殊文件)。

–d file

True(如果 file 存在且为目录)。

–e file

True(如果 file 存在)。(sh 中未提供。)

–f file

True(如果 file 存在且为正规文件)。或者,/usr/bin/sh 用户在 PATH 环境变量中先指定 /usr/ucb 再指定 /usr/bin 时,如果 file 存在且为 (not−a−directory),test 将返回 true。csh test[ 内置命令始终采用这种备用行为。

–g file

True(如果 file 存在且设置了其 set-group-ID 标志)。

–G file

True(如果 file 存在且其组与该进程的有效组 ID 匹配)。(sh 中未提供。)

–h file

True(如果 file 存在且为符号链接)。

–k file

True(如果 file 存在且设置了其 sticky 位)。

–L file

True(如果 file 存在且为符号链接)。

–n string

True(如果 string 的长度为非零值)。

–o option

True(如果已启用名为 option 的选项)。cshsh 中未提供该选项。

–O file

True(如果 file 存在且归该进程的有效用户 ID 所有)。sh 中未提供该选项。

–p file

True(如果 file 是指定管道 (FIFO))。

–r file

True(如果 file 存在且可读)。

–s file

True(如果 file 存在且其大小大于零)。

–S file

True(如果 file 存在且为套接字)。sh 中未提供该选项。

–t [file_descriptor]

True(如果文件描述符编号为 file_descriptor 的文件已打开且与终端相关联)。如果未指定 file_descriptor,则将 1 用作缺省值。

–u file

True(如果 file 存在且设置了其 set-user-ID 标志)。

–w file

True(如果 file 存在且可写)。True 只表示启用了写入标志。即使该测试表明 true,file 也无法在只读文件系统上写入。

–x file

True(如果 file 存在且可执行)。True 只表示启用了执行标志。如果 file 是目录,true 表示可以搜索 file

–z string

True(如果字符串 string 的长度为零)。

file1 –nt file2

True(如果 file1 存在且比 file2 更新)。sh 中未提供该选项。

file1 –ot file2

True(如果 file1 存在且比 file2 更旧)。sh 中未提供该选项。

file1 –ef file2

True(如果 file1file2 存在且指的是同一文件)。sh 中未提供该选项。

string

True(如果字符串 string 不是 null 字符串)。

string1 = string2

True(如果字符串 string1string2 相同)。

string1 != string2

True(如果字符串 string1string2 不同)。

n1 –eq n2

True(如果数字 n1n2 代数值相等)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

n1 –ne n2

True(如果数字 n1n2 代数值不等)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

n1 –gt n2

True(如果数字 n1 代数值大于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

n1 –ge n2

True(如果数字 n1 代数值大于或等于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

n1 –lt n2

True(如果数字 n1 代数值小于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

n1 –le n2

True(如果数字 n1 代数值小于或等于数字 n2)。数字可以是 C99/XPG6/SUS 所指定任意格式的整数、浮点或浮点常量(例如 [+/-]Inf、[+/-]NaN)。

condition1 –a condition2

True(如果 condition1condition2 均为 true)。–a 二元基元从左向右执行运算,其优先级高于 –o 二元基元。

condition1 –o condition2

True(如果 condition1condition2 为 true)。–o 二元基元从左向右执行运算。

这些基元可与以下运算符结合使用:

! condition

True(如果 condition 为 false)。

( condition )

True(如果 condition 为 true)。可以使用括号 ( ) 更改常规优先级和结合性。括号对 shell 有意义,因此必须用引号引起来。

确定运算符优先级的算法和生成的返回值基于提供给 test 的参数的数目。(但是,采用 [...] 格式时,右括号的最后一个参数并不计入这种算法。)

在以下列表中,$1$2$3$4 表示作为 conditioncondition1condition2 提供给 test 的参数。

0 个参数:

退出值为 false (1)。

1 个参数:

退出值为 true (0)(如果 $1 不为空)。否则,退出值为 false。

2 个参数:
  • $1! 时,如果 $2 为空,退出值为 true;如果 $2 不为空,退出值为 false。

  • $1 为一元基元时,如果一元测试为 true,退出值为 true;如果一元测试为 false,退出值为 false。

  • 否则,不会产生指定的结果。

3 个参数:
  • 如果 $2 为二元基元,将执行 $1$3 的二元测试。

  • 如果 $1!,将否定 $2$3 的两个参数的测试。

  • 否则,不会产生指定的结果。

4 个参数:
  • 如果 $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 一词

/usr/bin/test

示例 1 使用 /usr/bin/test

如果目录不存在,执行 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

csh

示例 5 使用 csh 内置命令
@ 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

ksh88

示例 6 使用 ksh88/ksh 内置命令
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)

退出状态

将返回以下退出值:

0

condition 评估结果为 true。

1

condition 评估结果为 false 或缺少 condition

>1

出现错误。

属性

有关下列属性的说明,请参见 attributes(5)

/usr/bin/test、csh、ksh88、sh

属性类型
属性值
可用性
system/core-os
接口稳定性
Committed(已确定)
标准
请参见 standards(5)

ksh

属性类型
属性值
可用性
system/core-os
接口稳定性
Uncommitted(未确定)

另请参见

csh(1)ksh(1)ksh88(1)sh(1)test(1B)attributes(5)environ(5)largefile(5)standards(5)

附注

not−a−directory 可以替代 –f 选项,但它只是在过渡期间对 BSD 应用程序起帮助作用,在未来的发行版中可能不再受支持。

XPG4 shksh88ksh

使用算术表达式,例如

$(( x > 3.1 )) #

而非

$ /usr/bin/test "$x" -gt 3.1 # )

-在比较两个浮点变量或一个常量和一个浮点变量以防止舍入误差(由 base16 到 base10 的转换造成)影响结果时。此外,XPG4 shksh88ksh 中支持的内置命令算术速度明显加快,因为无需对每项比较的字符串进行显式转换。