首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Linux C 讀取符號連結目標路徑:`readlink` 系統呼叫完整用法

     編輯:程式設計綜合問答

需求

已知符號連結路徑 `/aaa/`,欲取得其指向的真實路徑 `/bbb/`,不使用 `system()`/`popen()` 呼叫 `ls -l`。

核心函數:`readlink`

#include <unistd.h>
#include <limits.h>  // PATH_MAX
#include <stdio.h>

int main() {
    const char *linkpath = "/aaa/";
    char target[PATH_MAX];
    ssize_t len = readlink(linkpath, target, sizeof(target) - 1);
    if (len == -1) {
        perror("readlink");
        return 1;
    }
    target[len] = '\0'; // readlink 不自動加結束符
    printf("Target: %s\n", target);
    return 0;
}

關鍵細節

  • 緩衝區大小:建議 `PATH_MAX` (通常 4096);若路徑可能超過,需動態分配並重試 (`ERANGE`)。
  • 不跟隨遞迴:`readlink` 僅讀取**一層**連結;若目標仍為連結,需迴圈呼叫或使用 `realpath()` 一次解析至絕對路徑。
  • `realpath()` 替代方案:
char resolved[PATH_MAX];
if (realpath(linkpath, resolved)) {
    printf("Absolute target: %s\n", resolved);
}

`realpath()` 會解析所有中間符號連結、相對路徑 `.` `..`,回傳規範化絕對路徑。

錯誤處理

C++17 `std::filesystem` 現代寫法

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;
int main() {
    try {
        fs::path link = "/aaa/";
        if (fs::is_symlink(link)) {
            auto target = fs::read_symlink(link);
            std::cout << "Target: " << target << '\n';
            // 解析至絕對路徑
            std::cout << "Resolved: " << fs::canonical(link) << '\n';
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << e.what() << '\n';
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
errno原因
EINVAL非符號連結
ENOENT路徑不存在
EACCES權限不足
ERANGE緩衝區太小