温馨提示×

ubuntu copendir对符号链接咋处理

小樊
41
2026-10-17 07:22:28
栏目: 智能运维

在 Ubuntu(Linux)下,opendir() 对**符号链接(symbolic link)**的处理规则如下:


一、opendir() 的基本行为

DIR *opendir(const char *name);
  • opendir() 会跟随符号链接
  • 如果 name 是一个指向目录的符号链接,opendir() 会打开链接指向的真实目录
  • 如果 name 是一个指向文件的符号链接,opendir() 会失败,返回 NULL,并设置 errno = ENOTDIR

二、常见情况说明

1️⃣ 符号链接指向目录 ✅

symlink("/real/dir", "mylink");
DIR *d = opendir("mylink");  // 成功
  • 打开的是 /real/dir
  • readdir() 读到的是目标目录里的内容

2️⃣ 符号链接指向文件 ❌

symlink("/etc/passwd", "filelink");
DIR *d = opendir("filelink");  // 失败
  • 返回 NULL
  • errno == ENOTDIR

3️⃣ 符号链接本身就是一个目录项(不跟随)

opendir() 不会把符号链接当成“目录对象”来打开
它只关心最终指向的是什么


三、与 readdir() 的关系

readdir() 返回的结构体中:

struct dirent {
    ino_t d_ino;
    off_t d_off;
    unsigned short d_rendtl;
    unsigned char d_type;
    char d_name[256];
};
  • d_type 可能是:
    • DT_LNK:符号链接本身
    • DT_DIR:目录
  • 如果你在目录中读到符号链接:
    • opendir() 该链接名 → 会跟随
    • 想判断是否符号链接 → 用 lstat()

四、如果不想跟随符号链接?

opendir() 没有不跟随符号链接的版本

替代方案:

✅ 用 open() + fdopendir() + O_NOFOLLOW

int fd = open("mylink", O_RDONLY | O_NOFOLLOW | O_DIRECTORY);
if (fd == -1) {
    // 如果是符号链接,open 会失败 (ELOOP)
}
DIR *d = fdopendir(fd);

五、总结一句话

Ubuntu 下 opendir() 会跟随符号链接;指向目录则成功,指向文件则失败(ENOTDIR)。

如果你有具体代码场景(比如递归遍历目录、防止符号链接循环),我可以帮你写示例。

0 踩