我经常遇到这样的问题:某个程序(例如 apache)可能无法访问某个文件或目录。
解决这个问题意味着要手动检查文件和路径中直到根目录的每个目录,并查看程序的用户或组是否可以访问它。这很繁琐。
哪个程序能够自动告诉我问题出在哪里?
我想告诉程序路径、用户和组 - 它会告诉我问题在树中的哪个位置。请注意,我知道像符号链接与 Apache-FollowSymLinks
指令这样的问题无法通过这种方式检测到。
答案1
假设您拥有系统的 root 权限,您可以使用这个
sudo -u USER -g GROUP find ROOTDIR -exec test \! -r {} \; -ls
其中 USER 和 GROUP 应该替换为要评估访问权限的用户名和组名,而 ROOTDIR 是执行评估的目录树的顶级目录。
注意事项
请注意,sudo
必须进行适当配置,这意味着应该允许 root 充当任何用户以及任何组。
怎么运行的
该命令通过test
对 ROOTDIR 下的所有文件和目录执行该实用程序来工作。传递给该实用程序的选项使其在可能的情况下返回成功(零)退出代码。不是访问给定的文件或目录。然后,此退出代码将用于find
确定是否打印文件或目录的名称 ( -ls
)。
输出
输出是 USER:GROUP 执行的文件和目录列表不是可以访问有关每个文件和目录的额外信息,类似于输出ls -l
(即权限、所有权、修改时间等)。
你可以调整的有用的东西
-r
您可以通过替换不同的选项来测试不同类型的权限,请参阅男人测试。如果您不想要每个文件和目录的额外信息,而只想获取它们的名称,则可以将其替换-ls
为。请注意,如果命令找到无法遍历的目录,它也会在 stderr 上发出抱怨。根据您传递的内容,这可能是肤浅的,可以通过重定向删除。-print
test
答案2
我整理了这个简单的 shell[*] 脚本。在 root 权限下效果最佳:
my_path=/home/me/Documents/a/b/c/file.txt
while [[ "$my_path" != "/" ]] ; do
ls -lLd "$my_path"
my_path="`dirname \"$my_path\"`"
done
它仍然需要一些人工后期处理,但我不知道有什么优雅的方法来检查特定用户是否对目录具有 x 权限(它需要进行su -c "test -x"
繁琐的解析stat -t
)。
[*] 在 bash 和 ksh 中均可用
答案3
命令tree
将帮助你完成这项任务。
从man tree
:
Tree 是一个递归目录列表程序,可生成深度缩进的文件列表。
我建立了一个简单的示例来演示这种用法:
$ mkdir {a,b,c}/{1,2,3}
$ ls *
a:
1 2 3
b:
1 2 3
c:
1 2 3
$
$ tree
.
|-- a
| |-- 1
| |-- 2
| `-- 3
|-- b
| |-- 1
| |-- 2
| `-- 3
`-- c
|-- 1
|-- 2
`-- 3
12 directories, 0 files
$ sudo chown root b && sudo chmod go-rwx b
$ tree
.
|-- a
| |-- 1
| |-- 2
| `-- 3
|-- b [error opening dir]
`-- c
|-- 1
|-- 2
`-- 3
9 directories, 0 files
您可以以相关用户的身份运行tree
,以查看问题从何而来。您必须修复发现的问题并重新运行程序,直到没有错误才能将其用作修复工具,但是由于您可以使用它来tree -if
删除缩进并打印完整路径,因此您可以编写一个运行树的脚本,查找“打开目录时出错”,授予apache
对该目录的访问权限,然后重新启动。