需求
已知符號連結路徑 `/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()` 會解析所有中間符號連結、相對路徑 `.` `..`,回傳規範化絕對路徑。
錯誤處理
| errno | 原因 |
| EINVAL | 非符號連結 |
| ENOENT | 路徑不存在 |
| EACCES | 權限不足 |
| ERANGE | 緩衝區太小 |
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';
}
}
- 上一篇文章: jQuery 實作按鈕狀態切換:紅色「申請」↔ 灰色「已申請」並同步數量加一
- 下一篇文章: iOS `UITableView` Style=Grouped 頂部空白區移除:`heightForHeaderInSection` 回傳 0.001 技巧
Copyright ©
程式碼之家 All Rights Reserved