-l 詳細列表模式在基本 ls 基礎上新增長格式輸出,顯示檔案類型、權限、連結數、擁有者、群組、大小、修改時間、檔名。
stat() 取得 struct stat 完整屬性S_ISDIR() 等巨集判斷檔案類型 (目錄/一般/連結/字元/區塊/FIFO/Socket)st_mode & S_IRUSR 解析三組權限 (rwx)getpwuid(st_uid) 取得使用者名稱getgrgid(st_gid) 取得群組名稱ctime(&st_mtime) 格式化修改時間ls -l 格式對齊輸出void show_attr(char *name) {
struct stat buf;
struct passwd *pwd;
struct group *grp;
char type, perm[9] = "---------";
if (stat(name, &buf) == 0) {
// 檔案類型
if (S_ISLNK(buf.st_mode)) type = 'l';
else if (S_ISREG(buf.st_mode)) type = '-';
else if (S_ISDIR(buf.st_mode)) type = 'd';
else if (S_ISCHR(buf.st_mode)) type = 'c';
else if (S_ISBLK(buf.st_mode)) type = 'b';
else if (S_ISFIFO(buf.st_mode)) type = 'p';
else if (S_ISSOCK(buf.st_mode)) type = 's';
// 權限位元檢查
if (buf.st_mode & S_IRUSR) perm[0] = 'r';
if (buf.st_mode & S_IWUSR) perm[1] = 'w';
if (buf.st_mode & S_IXUSR) perm[2] = 'x';
if (buf.st_mode & S_IRGRP) perm[3] = 'r';
if (buf.st_mode & S_IWGRP) perm[4] = 'w';
if (buf.st_mode & S_IXGRP) perm[5] = 'x';
if (buf.st_mode & S_IROTH) perm[6] = 'r';
if (buf.st_mode & S_IWOTH) perm[7] = 'w';
if (buf.st_mode & S_IXOTH) perm[8] = 'x';
// 使用者/群組名稱
pwd = getpwuid(buf.st_uid);
grp = getgrgid(buf.st_gid);
// 格式化輸出
printf("%c%s %2ld %-4s %-4s %6ld %.12s %s\n",
type, perm, buf.st_nlink,
pwd ? pwd->pw_name : "?",
grp ? grp->gr_name : "?",
buf.st_size,
ctime(&buf.st_mtime) + 4, // 跳過星期
name);
} else {
perror("stat failed");
}
}
|-> ls -l
-rw-r--r-- 1 talk8 talk8 774 Dec 16 22:24 cat.c
-rw-r--r-- 1 talk8 talk8 596 Dec 13 09:59 cd.c
-rw-r--r-- 1 talk8 talk8 955 Dec 10 20:59 date.c
-rw-r--r-- 1 talk8 talk8 4326 Dec 17 23:05 ls.c
-rw-r--r-- 1 talk8 talk8 1139 Dec 17 23:03 main.c
-rw-r--r-- 1 talk8 talk8 611 Dec 17 23:02 main.h
-rw-r--r-- 1 talk8 talk8 256 Dec 10 20:59 pwd.c
-rwxr-xr-x 1 talk8 talk8 12916 Dec 17 23:05 s
struct stat是檔案元資料的核心結構,掌握其欄位與巨集是系統程式設計基礎。實作ls -l是理解 Unix 檔案系統介面的最佳練習。