Linux test 指令
test 是 Linux 系统中一个功能强大的 shell 内置命令,用于评估条件表达式,返回真(0)或假(非零)退出状态。它广泛用于 shell 脚本中的条件判断,如检查文件属性、比较字符串或数字,以及逻辑运算。test 命令通常与 if、while 等控制结构结合,是 Bash 脚本实现逻辑控制的核心工具。尽管 test 本身不产生输出,但其退出状态决定了脚本的执行流程。
📚 什么是 test 指令?
概述
test 是 Bash、Zsh 等 shell 的内置命令,用于评估条件表达式并根据结果返回退出状态。它的主要作用是检查文件、字符串、数字或变量的状态,生成逻辑真(退出状态 0)或假(非零退出状态,通常为 1)。test 命令通常以 [ … ] 的形式出现(称为测试命令),是 shell 脚本中条件判断的基础工具。test 遵循 POSIX 标准,广泛支持于 Linux 和 Unix 系统,内置于所有主流 shell 环境。
核心概念
- 条件表达式:test 评估的表达式,包括文件测试、字符串比较、数值比较和逻辑运算。
- 退出状态:
- 0:表达式为真。
- 非零(如 1):表达式为假。
- 测试命令:[ … ] 是 test 的等效形式,需以空格分隔内容并以 ] 结尾。
- 操作符:
- 文件测试:如 -f(普通文件)、-d(目录)。
- 字符串比较:如 =(相等)、-z(空字符串)。
- 数值比较:如 -eq(等于)、-gt(大于)。
- 逻辑运算:如 &&(与)、||(或)、!(非)。
- 标准输出:test 不直接输出结果,仅通过退出状态影响脚本流程。
核心特点
- 灵活性:支持多种测试类型(文件、字符串、数字)。
- 兼容性:POSIX 标准,跨 shell 一致。
- 脚本友好:退出状态适合条件控制结构(如 if)。
- 轻量高效:作为内置命令,执行速度快。
- 组合性:支持逻辑运算和多条件组合。
基本语法
test 表达式
# 或
[ 表达式 ]
参数说明
- 表达式:要评估的条件,如 -f file 或 string1 = string2。
- 注意:
- 使用 [ 时,[ 和 ] 必须与表达式内容用空格分隔。
- 表达式可以是单一条件或通过逻辑操作符组合的复杂条件。
输出行为
-
不产生标准输出,仅返回退出状态。
-
可用 echo $? 查看退出状态:
test -f /etc/passwd echo $?
注意事项
- 空格要求:
- [ 和 ] 必须与内容间隔空格,如 [ -f file ] 而非 [ -f file].
- 变量引用:
- 变量需用双引号避免空值错误,如 [ “$var” = “value” ].
- shell 依赖:
- 行为可能因 shell 不同(如 Bash vs Zsh),但 POSIX 核心功能一致。
- 退出状态:
- 脚本中需通过控制结构(如 if)处理退出状态。
- 操作符优先级:
- 逻辑操作符需用括号或明确分组以避免歧义。
🔧 test 的常见用途
应用场景
- 文件检查:验证文件是否存在、类型或权限。
- 字符串处理:比较字符串内容或检查是否为空。
- 数值判断:比较整数大小或相等性。
- 脚本逻辑:实现条件分支、循环控制。
- 自动化任务:在脚本中动态检查环境状态。
🛠️ 基础用法与示例
准备工作
以下示例假设运行在 Bash shell(如 Ubuntu 22.04 或 CentOS 8,当前时间为 2025-06-03 09:44 CST)。我们将使用常见文件(如 /etc/passwd)、变量和数字演示 test 的功能。假设当前目录为 /home/user,并创建以下测试文件:
touch testfile.txt
mkdir testdir
示例 1:检查文件是否存在
命令
[ -f /etc/passwd ]
echo $?
解释
- -f:检查是否为普通文件。
- /etc/passwd:系统用户文件,通常存在。
输出示例
0
说明
- 返回 0 表示文件存在且为普通文件。
示例 2:检查目录是否存在
命令
[ -d /home/user/testdir ]
echo $?
解释
- -d:检查是否为目录。
输出示例
0
说明
- 目录存在,返回真。
示例 3:字符串相等比较
命令
STR1="hello"
STR2="hello"
[ "$STR1" = "$STR2" ]
echo $?
解释
- =:比较字符串是否相等。
- 变量用双引号避免空值错误。
输出示例
0
示例 4:检查字符串是否为空
命令
VAR=""
[ -z "$VAR" ]
echo $?
解释
- -z:检查字符串是否为空(长度为 0)。
输出示例
0
示例 5:数值比较
命令
NUM1=10
NUM2=20
[ "$NUM1" -lt "$NUM2" ]
echo $?
解释
- -lt:检查是否小于(less than)。
输出示例
0
示例 6:逻辑运算
命令
[ -f /etc/passwd ] && [ -d /etc ]
echo $?
解释
- &&:逻辑与,两个条件都为真时返回真。
输出示例
0
🚀 常用测试操作符
以下是 test 常用的操作符,分为文件测试、字符串测试和数值比较。
📂 文件测试操作符
| 操作符 | 描述 | |-------------|--------|-------------| | -e | 存在 | | -f | 普通文件 | | -d | 目录 | | -r | 可读 | | -w | 可写 | | -x | 可执行 | | -s | 非空 | | -L | 符号链接 |
示例
[ -r /etc/passwd ] && echo "Readable"
🔤 字符串操作符
操作符 | 描述 |
---|---|
-z | 字符串为空 |
-n | 字符串非空 |
= | 字符串相等 |
!= | 字符串不等 |
< | 按 ASCII 小于 |
> | 按 ASCII 大于 |
示例
[ "$USER" = "root" ] && echo "Root user"
🔢 数值比较操作符
操作符 | 描述 |
---|---|
-eq | 等于 |
-ne | 不等于 |
-gt | 大于 |
-ge | 大于等于 |
-lt | 小于 |
-le | 小于等于 |
示例
[ 5 -gt 3 ] && echo "5 > 3"
🌟 高级用法
概述
test 的高级用法结合逻辑运算、复杂条件和脚本,适合自动化和复杂逻辑控制。
🛡️ 1. 组合逻辑运算
命令
FILE=/etc/passwd
[ -f "$FILE" ] && [ -r "$FILE" ] && [ -s "$FILE" ] && echo "Valid file"
解释
- 检查文件存在、可读且非空。
- 使用 && 组合条件。
输出示例
Valid file
🔍 2. 使用或运算
命令
[ "$USER" = "root" ] || [ "$USER" = "admin" ] && echo "Privileged user"
解释
- ||:逻辑或,任意条件为真则真。
输出示例
Privileged user
🔄 3. 嵌套条件
脚本
#!/bin/bash
FILE=testfile.txt
if [ -f "$FILE" ]; then
if [ -w "$FILE" ]; then
echo "File is writable"
else
echo "File is not writable"
fi
else
echo "File does not exist"
fi
解释
- 嵌套 if 结合 test 检查文件状态。
输出示例
File is writable
⚡ 4. 检查变量定义
命令
[ -v VAR ] && echo "VAR is defined"
解释
- -v:检查变量是否定义(Bash 4.2+)。
输出示例
VAR is defined
🔐 5. 错误处理
脚本
#!/bin/bash
DIR=/home/user/testdir
if [ ! -d "$DIR" ]; then
mkdir -p "$DIR" || {
echo "Failed to create $DIR" >&2
exit 1
}
echo "Created $DIR"
else
echo "$DIR exists"
fi
解释
- !:逻辑非,检查目录不存在。
- 创建目录并处理错误。
输出示例
Created /home/user/testdir
⚠️ 使用 test 时的注意事项
- 空格要求:
- [ 和 ] 必须与内容间隔空格。
- 变量引用:
- 总是用双引号,如 [ “$var” = “” ],避免空值错误。
- 数值比较:
- 使用 -eq 等操作符,不能用 = 或 <。
- 字符串比较:
- < 和 > 需转义(如 <),否则被解析为重定向。
- 逻辑运算符:
- 在 [ … ] 内,使用 -a(与)、-o(或),但优先使用 && 和 ||。
- Bash 扩展:
- 某些操作符(如 -v)仅 Bash 支持,注意兼容性。
🛠️ 高级技巧与实战案例
概述
以下是高级技巧和实战案例,展示 test 在复杂脚本中的应用。
🖥️ 案例 1:文件备份脚本
脚本
#!/bin/bash
SRC_FILE=/home/user/data.txt
BACKUP_DIR=/home/user/backup
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
if [ ! -f "$SRC_FILE" ]; then
echo "Error: $SRC_FILE does not exist" >&2
exit 1
fi
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR" || {
echo "Error: Failed to create $BACKUP_DIR" >&2
exit 1
}
fi
cp "$SRC_FILE" "$BACKUP_DIR/data_${TIMESTAMP}.txt"
echo "Backed up $SRC_FILE to $BACKUP_DIR/data_${TIMESTAMP}.txt"
解释
- 检查源文件和备份目录。
- 创建备份并处理错误。
输出示例
Backed up /home/user/data.txt to /home/user/backup/data_20250603_094400.txt
📦 案例 2:批量文件检查
脚本
#!/bin/bash
DIR=/home/user/docs
LOG_FILE=/tmp/file_check.log
echo "File Check: $(date)" > "$LOG_FILE"
find "$DIR" -type f | while read file; do
if [ -r "$file" ] && [ -s "$file" ]; then
echo "$file is readable and non-empty" >> "$LOG_FILE"
else
echo "$file is not readable or empty" >> "$LOG_FILE"
fi
done
cat "$LOG_FILE"
解释
- 检查目录中文件的可读性和大小。
- 记录结果到日志。
输出示例(file_check.log)
File Check: Tue Jun 3 09:44:00 CST 2025
/home/user/docs/file1.txt is readable and non-empty
/home/user/docs/file2.txt is not readable or empty
🔒 案例 3:用户权限验证
脚本
#!/bin/bash
if [ "$USER" = "root" ] || [ "$UID" -eq 0 ]; then
echo "Running as root"
else
echo "Please run as root" >&2
exit 1
fi
解释
- 检查用户是否为 root(通过 $USER 或 $UID)。
输出示例
Please run as root
📈 案例 4:磁盘空间监控
脚本
#!/bin/bash
THRESHOLD=90
USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "Warning: Disk usage is $USAGE%, exceeds $THRESHOLD%" >&2
exit 1
else
echo "Disk usage is $USAGE%, below $THRESHOLD%"
fi
解释
- 检查根分区使用率。
- 超过阈值时报警。
输出示例
Disk usage is 85%, below 90%
🔧 案例 5:自动化任务调度
脚本
#!/bin/bash
LOG_FILE=/tmp/task.log
SRC_DIR=/home/user/docs
BACKUP_DIR=/tmp/backup
if [ ! -d "$SRC_DIR" ]; then
echo "Error: $SRC_DIR does not exist" | tee -a "$LOG_FILE"
exit 1
fi
mkdir -p "$BACKUP_DIR"
find "$SRC_DIR" -type f | while read file; do
if [ -f "$file" ] && [ -r "$file" ]; then
cp "$file" "$BACKUP_DIR"
echo "Backed up $file" | tee -a "$LOG_FILE"
fi
done
加入 cron
crontab -e
0 2 * * * /path/to/backup.sh
解释
- 检查源目录和文件状态。
- 备份文件并记录日志。
- 每天凌晨 2 点运行。
输出示例(task.log)
Backed up /home/user/docs/file1.txt
Backed up /home/user/docs/file2.txt
🔗 结合其他工具
-
With find:
find /home/user -type f -exec test -f {} \; -print
-
With awk:
df / | awk 'NR==2 {if ($5+0 > 90) print "Disk full"}'
-
With tee:
[ -f file.txt ] && echo "File exists" | tee log.txt
📝 总结
test 是 Linux shell 中条件判断的核心工具,通过评估文件、字符串和数字状态,提供强大的逻辑控制能力。本文从基础到高级,结合示例和注意事项,全面介绍了 test 的功能。无论是文件检查、字符串处理还是自动化脚本,test 都是不可或缺的工具。