-e仅判断路径节点是否存在,不区分类型或权限;安全写法应先[ -e "$path" ] && [ -f "$path" ],避免toctou风险及旧shell兼容问题。

-e 是最直接的判断方式,但实际用错最多
用 [ -e filename ] 判断文件存在性,看起来简单,但很多人忽略它不区分文件类型,也不检查权限。比如符号链接指向的源文件已删除,-e 仍返回真(因为链接本身存在);又或者文件存在但当前用户无访问权限,-e 依然为真——它只管“路径节点是否存在”,不管“你能不能碰它”。
- 真正想确认“能读取这个文件”?该用
[ -f filename ] && [ -r filename ] - 只想删掉一个可能存在的普通文件?优先用
-f而非-e,避免误删目录 - 脚本中变量未加引号时,
[ -e $file ]遇到空格或通配符会报错,必须写成[ -e "$file" ]
-f 和 -d 必须配合 -e 使用才稳妥
-f 和 -d 各自隐含了“存在”前提,但 POSIX 标准并未强制要求实现如此。某些老版本 shell 或最小化系统(如 BusyBox ash)中,[ -f /nonexistent ] 可能直接报错或返回不可靠状态。安全写法是先 -e 再细分类型:
[ -e "$path" ] && [ -f "$path" ]
这样既兼容旧环境,又明确表达了逻辑:先确保路径存在,再判断是不是普通文件。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
-d对软链接默认返回假,除非链接指向的是目录且可解析 -
-L或-h才能可靠识别符号链接本身(不是它指向的目标) - 用
stat或ls -ld查看真实类型时,注意ls -l输出首字符:-是普通文件,d是目录,l是链接
在脚本里别依赖单次判断做关键操作
文件状态可能在 if 判断后、执行前瞬间改变(TOCTOU 问题)。比如:
if [ -f "$log" ]; then rm "$log"; fi
这段代码在高并发或恶意环境下有风险:判断时文件存在,但 rm 执行前被替换成符号链接,就可能误删其他文件。
- 真正要删除?改用
rm -f "$log",让rm自己处理“不存在”情况 - 要读取并处理?用重定向加错误捕获:
if data=$(cat "$config" 2>/dev/null); then ... fi - 需要原子性保障?考虑用
ln -nfs替换配置,或借助flock加锁
最常被忽略的是:[ 是个命令,不是语法糖,它的退出码决定逻辑分支——哪怕写成 [[,也要注意 Bash 与 Dash 的行为差异,尤其在 shebang 写 #!/bin/sh 时。










