在 Debian(以及其他 Linux 发行版)里,opendir() 失败绝大多数情况都是权限问题。下面按常见原因 + 排查方法 + 解决方式给你一个实用清单。
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
DIR *d = opendir(path);
if (!d) {
fprintf(stderr, "opendir failed: %s\n", strerror(errno));
}
常见 errno:
EACCES:权限不足(最常见)ENOENT:目录不存在ENOTDIR:不是目录EMFILE / ENFILE:文件描述符耗尽目录需要:
r:列出内容x:进入目录ls -ld /some/dir
示例:
drwx------ 2 root root 4096 dir
→ 非 root 用户 opendir() 必失败(EACCES)
✅ 解决:
chmod 755 /some/dir
或
chown user:user /some/dir
即使目标目录权限正确,父目录必须有 x 权限
例如:
/srv/data/logs
如果 /srv/data 是:
drwxr-x--- root root
普通用户无法进入,也会 EACCES
✅ 检查:
namei -l /srv/data/logs
某些服务(如 nginx、mysql、php-fpm)受 AppArmor 限制:
aa-status
✅ 临时验证:
sudo aa-complain /usr/sbin/nginx
✅ 或查看拒绝日志:
sudo dmesg | grep apparmor
journalctl | grep apparmor
如:
/root/etc/var/lib✅ 解决:
service 文件可能限制:
[Service]
User=www-data
ProtectHome=true
ReadWritePaths=/data
✅ 检查:
systemctl cat your.service
如:
root_squash✅ 检查:
mount | grep dir
# 1. 确认目录存在
ls -ld /path
# 2. 确认当前用户
whoami
# 3. 确认权限链
namei -l /path
# 4. 确认 AppArmor
aa-status
# 5. 程序内打印 errno
perror("opendir");
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[]) {
DIR *d = opendir(argv[1]);
if (!d) {
printf("opendir(%s) failed: %s\n", argv[1], strerror(errno));
return 1;
}
closedir(d);
return 0;
}
如果你能贴:
我可以直接帮你定位是哪一层权限卡住的。