为什么 test -e 对仅具有读取权限的目录中的文件失败?

为什么 test -e 对仅具有读取权限的目录中的文件失败?

根据我对目录读取权限的理解,它允许列出目录中的文件,仅此而已。

给定一个具有 0744 权限的目录,所有者为userA

[userA@localhost ~]$ mkdir -m 0744 /tmp/semi-secret
[userA@localhost ~]$ ls -ld /tmp/semi-secret/
drwxr--r--. 2 userA userA 6 Aug 29 10:15 /tmp/semi-secret/
[userA@localhost tmp]$ touch semi-secret/foobar.txt
[userA@localhost tmp]$ chmod 0600 semi-secret/foobar.txt

To ,从命令中可以看出userB该文件的存在。foobar.txtls

[userB@localhost ~]$ ls -l /tmp/semi-secret/
ls: cannot access /tmp/semi-secret/foobar.txt: Permission denied
total 0
-????????? ? ? ? ?            ? foobar.txt

但为什么test -e命令会以非零状态退出?!它唯一的工作是确认文件是否存在,并且目录权限应该允许这样做。

[userB@localhost ~]$ test -e /tmp/semi-secret/foobar.txt || echo "The file doesn't exist."
The file doesn't exist.

答案1

由于即使stat(2)系统调用也无法对目录中缺少x权限位的任何文件起作用,因此基于stat(2)系统调用的任何操作都将在此类目录中失败。

如果您的目录设置了该r位,您确实可以使用 读取该目录的内容readdir(),但不能statopen任何文件。

相反,如果您知道相关文件名但无法检索相关目录的内容,则x设置了该位的目录允许您stat(2)或文件。openreaddir()

test -e如果文件不存在(在符号链接解析之后,因此也适用于),则以非零状态退出现存的符号链接到不存在的或不可访问的文件)或尝试访问stat(2)相关文件时发生任何错误。

答案2

为了补充@schily的好答案,一种检查您是否具有读取访问权限但不一定具有给定目录的方法搜索访问,包含给定名称的条目是读取该目录的内容并查找该文件名。

您可以使用 shell 通配符来实现这一点。

set -- /tmp/semi-secret/[f]oobar.txt
if [ "$1" = /tmp/semi-secret/foobar.txt ]; then
  echo exists
fi

使用zsh,您还可以执行以下操作:

if ()(($#)) /tmp/semi-secret/foobar.txt(N); then
  echo exists
fi

通过find支持的实现-maxdepth

if find /tmp/semi-secret -mindepth 1 -maxdepth 1 -name foobar.txt -print |
     grep -q '^'; then
  echo exists
fi

除了zsh解决方案之外,它很难适应任意文件名。

相关内容