shell/test/ target=_blank class=infotextkey>shell test命令最短的定义可能是评估一个表达式;
如果条件为真,则返回一个 0 值。如果表达式不为真,则返回一个大于 0 的值 — 也可以将其称为假值。
检查最后所执行命令的状态的最简便方法是使用 $? 值。
test 命令期望在命令行中找到一个参数,当 shell 没有为变量赋值时,则将该变量视为空。这意味着在处理脚本时,一旦脚本寻找的参数不存在,则 test 将报告该错误。
当试图保护脚本时,您可以通过将所有参数包含在双引号中来解决这个问题。然后 shell 将变量展开,如果变量没有值,那么将传递一个空值给 test。另一种方法是在脚本内增加一个额外检查过程来判断是否设置了命令行参数。如果没有设置命令行参数,那么脚本会告诉用户缺少参数,然后退出。我们 会通过一些例子来更具体地说明所有这些内容。
test 和 [ 命令
虽然 linux 和 UNIX 的每个版本中都包含 test 命令,但该命令有一个更常用的别名 — 左方括号:[。test 及其别名通常都可以在 /usr/bin 或 /bin (取决于操作系统版本和供应商)中找到。
当您使用左方括号而非 test 时,其后必须始终跟着一个空格、要评估的条件、一个空格和右方括号。右方括号不是任何东西的别名,而是表示所需评估参数的结束。
条件两边的空格是必需的,这表示要调用 test,以区别于同样经常使用方括号的字符/模式匹配操作。
test 和 [ 的语法如下:
test expression
[ expression ]
在这两种情况下,test 都评估一个表达式,然后返回真或假。如果它和 if、while 或 until 命令结合使用,则您可以对程序流进行广泛的控制。
不过,无需将 test 命令与任何其它结构一起使用;
可以从命令行直接运行它来检查几乎任何东西的状态。
因为它们彼此互为别名,所以使用 test 或 [ 均需要一个表达式。表达式一般是文本、数字或文件和目录属性的比较,并且可以包含变量、常量和运算符。
运算符可以是字符串运算符、整数运算符、文件运算符或布尔运算符 — 我们将在以下各部分依次介绍每一种运算符。
test 文件运算符
利用这些运算符,您可以在程序中根据对文件类型的评估结果执行不同的操作:
-b file 如果文件为一个块特殊文件,则为真
-c file 如果文件为一个字符特殊文件,则为真
-d file 如果文件为一个目录,则为真
-e file 如果文件存在,则为真
-f file 如果文件为一个普通文件,则为真
-g file 如果设置了文件的 SGID 位,则为真
-G file 如果文件存在且归该组所有,则为真
-k file 如果设置了文件的粘着位,则为真
-O file 如果文件存在并且归该用户所有,则为真
-p file 如果文件为一个命名管道,则为真
-r file 如果文件可读,则为真
-s file 如果文件的长度不为零,则为真
-S file 如果文件为一个套接字特殊文件,则为真
-t fd 如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真
-u file 如果设置了文件的 SUID 位,则为真
-w file 如果文件可写,则为真
-x file 如果文件可执行,则为真
shell test [命令用法
简单操作的运行情况:
$ ls -l
total 33
drwxr-xr-w 2 root root 1024 Dec 5 05:05 LST
-rw-rw-rw- 1 emmett users 27360 Feb 6 07:30 evan
-rwsrwsrwx 1 root root 152 Feb 6 07:32 hannah
drwxr-xr-x 2 emmett users 1024 Feb 6 07:31 karen
-rw------- 1 emmett users 152 Feb 6 07:29 kristin
-rw-r--r-- 1 emmett users 152 Feb 6 07:29 spencer
$
$ test -r evan
$ echo $?
0
$ test -r walter
$ echo $?
1
$
由于第一次评估为真 — 文件存在且可读 — 返回值为真,或 0。由于第二次评估的文件不存在,该值为假,返回值不为零。
将值指定为零或非零很重要,因为在失败时不会始终返回 1(虽然这是通常返回的值),可能返回一个非零值。
正如开头所提到的,除了使用 test 外,还可以用方括号 [ ] 将命令括住来向 shell 发出同样的命令 — 如下:
$ [ -w evan ]
$ echo $?
0
$ [ -x evan ]
$ echo $?
1
$
同样,第一个表达式为真,第二个表达式为假 — 正如返回值所指示的那样。您还可以使用以下命令将两个文件彼此进行比较:
file1 -ef file2 测试以判断两个文件是否与同一个设备相连,是否拥有相同的 inode 编号
file1 -nt file2 测试以判断第一个文件是否比第二个文件更新(由修改日期决定)
file1 -ot file2 测试以判断第一个文件是否比第二个文件更旧
以下示例显示了使用这些运算符比较文件的结果:
$ [ evan -nt spencer ]
$ echo $?
0
$ [ karen -ot spencer ]
$ echo $?
1
$
名为 evan 的文件比名为 spencer 的文件更新,因而评估为真。类似地,名为 karen 的文件比名为 spencer 的文件更新,因此该评估为假。
字符串比较运算符
如标题所示,这组函数比较字符串的值。您可以检查它们是否存在、是否相同或者是否不同。
String 测试以判断字符串是否不为空
-n string 测试以判断字符串是否不为空;字符串必须为 test 所识别
-z string 测试以判断字符串是否为空;字符串必须为 test 所识别
string1 = string2 测试以判断 string1 是否与 string2 相同
string1 != string2 测试以判断 string1 是否与 string2 不同
对任何变量进行的最有用的测试之一是判断它的值是否不为空,可以简单地将其放在 test 命令行中执行这种测试,如下例所示:
$ test "$variable"
强烈建议进行此种测试时用双引号将变量括住,以让 shell 识别变量(即使变量为空)。默认情况下执行的基本字符串评估和 -n 测试从功能上讲是相同的,如下:
#example1
if test -n "$1"
then
echo "$1"
fi
执行以上例子中代码,将根据 $1 是否存在给出以下结果:
$ example1 friday
friday
$
$ example1
$
如果将代码更改为以下形式,则结果将相同:
#example2
if test "$1"
then
echo "$1"
fi
如下:
$ example2 friday
friday
$
$ example2
$
所有这些表明,通常不需要 -n,它代表默认操作。
要从一个不同的角度来查看各种可能性,可以用另一个选项来替换 -n,并检查该值是否为空(相对于非空)。这可以用 -z 选项来实现,代码为:
#example3
if test -z "$1"
then
echo "no values were specified"
fi
运行如下:
$ example3
no values were specified
$ example3 friday
$
如果在没有命令行参数的情况下运行该程序,而表达式评估为真,那么将执行程序块中的文本。
如果在命令行中有值,则脚本退出,不执行任何操作。将评估操作放在脚本的开头非常有用,这可以在可能产生错误的进一步处理之前预先检查变量值。
附,shell test命令常用选项与语法。
test命令用法。
功能:检查文件和比较值
1)判断表达式
2)判断字符串
3)判断整数
4)判断文件