Skip to content

文件测试

Shell 提供了丰富的文件测试运算符,用于判断文件类型、权限和状态。

测试语法

bash
# 方式一:test 命令
test -选项 文件

# 方式二:[ ] 语法
[ -选项 文件 ]

# 方式三:[[ ]] 语法(Bash 扩展)
[[ -选项 文件 ]]

文件类型测试

选项说明
-e文件或目录是否存在
-f是否为普通文件
-d是否为目录
-l是否为符号链接
-b是否为块设备文件
-c是否为字符设备文件
-p是否为命名管道
-s是否为 socket 文件
bash
# 判断文件是否存在
if [ -e "/etc/hosts" ]; then
    echo "文件存在"
fi

# 判断是否为普通文件
if [ -f "script.sh" ]; then
    echo "是普通文件"
fi

# 判断是否为目录
if [ -d "/tmp" ]; then
    echo "是目录"
fi

# 判断是否为符号链接
if [ -l "/usr/bin/python" ]; then
    echo "是符号链接"
fi

文件权限测试

选项说明
-r当前用户是否可读
-w当前用户是否可写
-x当前用户是否可执行
-u是否设置了 SUID 位
-g是否设置了 SGID 位
-k是否设置了粘滞位
bash
# 判断文件是否可读
if [ -r "file.txt" ]; then
    cat file.txt
fi

# 判断文件是否可执行
if [ -x "script.sh" ]; then
    ./script.sh
else
    echo "没有执行权限"
fi

# 判断文件是否可写
if [ -w "log.txt" ]; then
    echo "日志内容" >> log.txt
fi

文件大小测试

选项说明
-s文件大小是否大于 0(非空)
-z字符串是否为空(注意:非文件选项)
bash
# 判断文件是否非空
if [ -s "data.txt" ]; then
    echo "文件有内容"
else
    echo "文件为空"
fi

文件比较测试

选项说明
f1 -nt f2f1 是否比 f2 新(修改时间更晚)
f1 -ot f2f1 是否比 f2 旧
f1 -ef f2f1 和 f2 是否为同一文件(硬链接)
bash
# 比较文件新旧
if [ "backup.tar" -ot "data.txt" ]; then
    echo "需要重新备份"
fi

# 判断是否为同一文件
if [ "link.txt" -ef "original.txt" ]; then
    echo "是同一个文件"
fi

综合示例

bash
#!/bin/bash

check_file() {
    local file="$1"

    if [ ! -e "$file" ]; then
        echo "$file 不存在"
        return 1
    fi

    echo "=== $file 信息 ==="
    [ -f "$file" ] && echo "类型:普通文件"
    [ -d "$file" ] && echo "类型:目录"
    [ -l "$file" ] && echo "类型:符号链接"
    [ -r "$file" ] && echo "权限:可读"
    [ -w "$file" ] && echo "权限:可写"
    [ -x "$file" ] && echo "权限:可执行"
    [ -s "$file" ] && echo "大小:非空" || echo "大小:空文件"
}

check_file "/etc/hosts"
check_file "/tmp"

逻辑组合

bash
# 与(&&)
if [ -f "file.txt" ] && [ -r "file.txt" ]; then
    echo "文件存在且可读"
fi

# 或(||)
if [ -f "a.txt" ] || [ -f "b.txt" ]; then
    echo "至少一个文件存在"
fi

# 非(!)
if [ ! -d "logs" ]; then
    mkdir logs
fi