CentOS与Ubuntu中‘regular file(普通文件)’的定义及验证疑问
解析
test -f对符号链接的检查逻辑 嘿,我完全理解你对test -f里“regular file”定义的疑惑——毕竟符号链接的存在很容易让这个选项的实际行为看起来和手册描述有出入,结合你做的操作,我来给你拆解清楚:
首先明确GNU coreutils 8.4中test -f的核心行为:当你用它检查符号链接时,它会自动解引用这个链接,去验证链接指向的目标文件是否是普通文件,同时要求这个符号链接本身必须存在。
我们结合你的操作一步步看:
- 你创建了普通文件
afile:$ touch afile - 接着创建了指向
afile的软链接LN-FILE:$ ln -fs afile LN-FILE - 你的脚本
check_file_exist_180320_exec(这里注意你脚本里写的是LN-file,和实际创建的LN-FILE大小写不一致,CentOS和Ubuntu都是大小写敏感的系统,如果是笔误的话,我们假设文件名统一为LN-FILE):
#!/usr/bin/env bash if [ -e LN-FILE ] then echo "file exists [-e]" fi if [ -f LN-FILE ] then echo "file exists [-f]" fi
两个选项的具体表现
-e LN-FILE:这个选项只检查文件实体是否存在,不管它是什么类型(软链接、目录、普通文件都算)。因为LN-FILE这个软链接本身已经被创建出来了,所以这个判断会返回真,输出file exists [-e]。-f LN-FILE:这个选项会先确认LN-FILE存在,然后自动解引用它,去检查链接指向的afile是否是普通文件。由于afile是你用touch创建的标准普通文件,所以这个判断也会返回真,输出file exists [-f]。
延伸测试场景
如果我们修改软链接指向一个不存在的文件:
$ ln -fs non-existent-file LN-FILE
再运行脚本的话:
-e LN-FILE仍然会返回真(因为软链接本身还在);-f LN-FILE会返回假(解引用后目标文件不存在,自然不是普通文件)。
如何只检查“文件本身是普通文件(不是软链接)”
如果你想跳过解引用,只判断当前文件实体本身是否是普通文件(排除软链接的情况),可以结合-L(检查是否是软链接)来反向判断:
if [ -f LN-FILE ] && ! [ -L LN-FILE ]; then echo "这是一个真正的普通文件,不是软链接" fi
这个行为不是GNU特有的,而是符合POSIX标准的——手册里的“regular file”指的是解引用后的最终目标类型,而非符号链接本身(符号链接属于单独的文件类型)。在CentOS 6.9和Ubuntu 16.04上,只要使用的是GNU coreutils 8.4,这个表现是完全一致的。
内容的提问来源于stack exchange,提问作者sevenOfNine
相关产品推荐
相关产品推荐

