介绍
test 是 shell 内置的条件判断命令,用来做文件、字符串、数值比较;返回退出码:0 代表真,非0 代表假。
语法
test expression
等价写法
[ 条件 ],注意 [ 后面、] 前面必须有空格。
[[ ]] 是 bash 扩展,不是标准 test,后面会区分。
# 两种写法完全等价(POSIX test)
[ expression ]
一、返回值规则
test 1 -gt 0
echo $? # 0:条件成立
test 1 -lt 0
echo $? # 1:条件不成立
二、数值比较(只用于整数,不能浮点数)
语法:test 整数1 OP 整数2
| 参数 | 含义 |
|---|---|
-eq |
equal 等于 |
-ne |
not equal 不等于 |
-gt |
greater than 大于 |
-ge |
greater or equal 大于等于 |
-lt |
less than 小于 |
-le |
less or equal 小于等于 |
示例:
a=10
test $a -eq 10
[ $a -gt 5 ] && echo yes
⚠️ 坑:数值比较只能整数;变量为空会报错,建议加引号:
[ "$a" -gt 5 ]
三、字符串判断
| 表达式 | 说明 |
|---|---|
-z "$str" |
字符串长度为0(空字符串) |
-n "$str" |
字符串长度非0(不为空) |
"$s1" = "$s2" |
字符串相等 |
"$s1" != "$s2" |
字符串不等 |
注意:字符串变量一定要双引号包裹,防止变量为空、带空格导致语法错误!
str=""
test -z "$str" && echo "空字符串"
str="hello"
test -n "$str" && echo "非空"
[ "$user" = "root" ]
⚠️ POSIX test 里字符串比较不能用 ==,
==是[[ ]]bash扩展。
四、文件测试(高频)
| 参数 | 含义 |
|---|---|
-e file |
文件存在(不管类型:普通文件/目录/链接) |
-f file |
存在且是普通文件 |
-d file |
存在且是目录 |
-L file |
存在且是符号链接 |
-r file |
文件可读 |
-w file |
文件可写 |
-x file |
文件可执行 |
-s file |
文件存在且大小>0(非空文件) |
-O file |
文件属主是当前用户 |
-G file |
文件属组是当前用户组 |
-nt |
file1 -nt file2:file1 更新(newer than) |
-ot |
file1 -ot file2:file1 更旧(older than) |
示例:
test -d /etc && echo "/etc 是目录"
[ -f "/etc/passwd" ] && echo "存在普通文件"
[ -s test.log ] || echo "文件为空或不存在"
五、逻辑运算(test 原生,不是 && ||)
test 使用 -a(and)、-o(or),! 取反
⚠️
-a/-o在部分场景有优先级坑,推荐用多个 test + shell 的 && || 代替
| 运算符 | 说明 |
|---|---|
! expr |
取反 |
expr1 -a expr2 |
逻辑与,两个都成立 |
expr1 -o expr2 |
逻辑或,任意一个成立 |
# 文件存在 并且 是普通文件
test -e "a.txt" -a -f "a.txt"
# 不是目录
! test -d "/tmp"
[ ! -d "/tmp" ]
推荐更安全写法(分开判断,shell逻辑连接):
[ -e "a.txt" ] && [ -f "a.txt" ]
六、test / [ ] 和 [[ ]] 的区别
test/[ ]:POSIX 标准,所有 shell(sh/bash/dash) 都支持- 字符串相等只能
=,不支持== - 没有正则匹配
- 变量不引号容易炸
- 字符串相等只能
[[ ]]:bash/ksh 扩展,不是标准 test- 支持
==、!=模式匹配(通配符) - 支持
=~正则匹配 - 内部空格处理更友好,不用对变量大量引号转义
# [[ ]] bash特有,不属于test命令 [[ "abc123" =~ ^abc ]]
- 支持
七、常见坑
[是命令,后面必须空格:[$a -gt 1]直接报错- 变量务必双引号:
[ -z $var ]当var为空时语法错误,写成[ -z "$var" ] -gt/-eq只能整数;浮点数要用bc比较-a / -o优先级问题,复杂条件不要用,拆成多个[] && []=是字符串比较,不要拿来比较数字:[ "10" = "2" ]做字符串比对,不是数值
八、速查表
# 数值
[ $a -eq $b ] 相等
[ $a -ne $b ] 不等
[ $a -gt $b ] >
[ $a -ge $b ] >=
[ $a -lt $b ] <
[ $a -le $b ] <=
# 字符串
[ -z "$s" ] 空串
[ -n "$s" ] 非空串
[ "$s1" = "$s2" ] 相等
[ "$s1" != "$s2" ] 不等
# 文件
[ -e path ] 存在
[ -f path ] 普通文件
[ -d path ] 目录
[ -L path ] 软链接
[ -r path ] 可读
[ -w path ] 可写
[ -x path ] 可执行
[ -s path ] 文件非空
# 逻辑
! [ expr ] 取反
[ e1 ] && [ e2 ] 与
[ e1 ] || [ e2 ] 或