人人都会AI编程

test 与 [] 判断语法

更新时间:2026-07-12

在 Shell 脚本中,条件判断是控制流程的基础。一个最常见的需求是检查“某个文件是否存在”或“两个字符串是否相等”。这套功能由 test 命令及它的别名 [ 提供。

1. test[ 是同一个命令

test 是一个用于条件测试的独立命令,而 [ 是它的一个符号化别名。当你在脚本中看到:

if [ -f /etc/passwd ]; then
    echo "文件存在"
fi

等价于:

if test -f /etc/passwd; then
    echo "文件存在"
fi

[ 只是一个普通的命令,它要求最后一个参数必须是 ],否则会报错。正是这个设计让条件表达式在代码中看起来更直观。

2. 常用的测试标志

所有测试条件都在 test/[ 的“参数”位置上,以短选项的形式出现。按用途大致分为三类:

文件测试

| 条件 | 含义 |
|------|------|
| -f 文件 | 文件存在且为普通文件 |
| -d 目录 | 目录存在 |
| -e 路径 | 路径存在(不限类型) |
| -r 文件 | 文件存在且可读 |
| -w 文件 | 文件存在且可写 |
| -x 文件 | 文件存在且可执行 |
| -s 文件 | 文件存在且大小大于 0 |

示例:

if [ -d /tmp ]; then
    echo "/tmp 是一个目录"
fi

字符串测试

| 条件 | 含义 |
|------|------|
| -z 字符串 | 字符串长度为 0(为空) |
| -n 字符串 | 字符串长度大于 0(非空) |
| 字符串1 = 字符串2 | 两字符串相等 |
| 字符串1 != 字符串2 | 两字符串不等 |

示例:

name=""
if [ -z "$name" ]; then
    echo "变量 name 为空"
fi

数值比较

| 条件 | 含义 |
|------|------|
| 整数1 -eq 整数2 | 等于(equal) |
| 整数1 -ne 整数2 | 不等于(not equal) |
| 整数1 -gt 整数2 | 大于(greater than) |
| 整数1 -lt 整数2 | 小于(less than) |
| 整数1 -ge 整数2 | 大于或等于 |
| 整数1 -le 整数2 | 小于或等于 |

示例:

count=5
if [ $count -gt 0 ]; then
    echo "count 为正数"
fi

3. 组合多个条件

  • ! 表达式:逻辑非
  • 表达式1 -a 表达式2:逻辑与(and)
  • 表达式1 -o 表达式2:逻辑或(or)

也可直接用 &&|| 连接两个 test 命令(不在单个 [ ] 内部):

[ -f file ] && [ -r file ] && echo "可读文件"

4. [ ][[ ]] 的区别

在 Bash 和其他一些高级 Shell 中,还有 [[ ]] 扩展语法。它的优势在于:

  • 支持 &&|| 直接在 [[ ]] 内部使用,比 -a-o 更清晰;
  • 支持正则匹配(如 [[ $str =~ ^[0-9]+$ ]]);
  • 不需要对变量使用双引号保护(在 [[ ]] 里空变量不会导致语法错误)。

但在追求最大兼容性(如 #!/bin/sh)的脚本中,通常只能使用 test/[ ]

5. 安全注意事项:始终给变量加上双引号

当使用 [ ] 时,必须给变量加双引号,否则变量为空或包含空格时会导致语法错误或判断异常:

# 错误写法(当 name 为空时,脚本报错)
if [ $name = "root" ]; then ...

# 正确写法
if [ "$name" = "root" ]; then ...

[[ ]] 则无需如此,因为它是一个 Shell 关键字,具备更智能的解析规则。

6. 在一行命令中使用 &&||

正因为 test 是一个命令,它可以作为一行命令中的条件控制:

[ -d /backup ] && tar -czf /backup/data.tgz /data || echo "备份目录不存在"

如果 [ -d /backup ] 成功,执行压缩;否则输出错误信息。这种写法在简单的运维脚本里十分常见,可读性高且简洁。

总之,test/[ ] 是 Shell 脚本的逻辑基石。掌握文件、字符串、数值三类判断,注意变量引号,并根据环境选择 [ ][[ ]],就能写出安全且清晰的自动化脚本。