Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Unix/Linux 檔案屬性與系統呼叫深度解析:stat 族群、檔案類型、權限與時間戳記

編輯:Linux 教學

檔案屬性是作業系統管理資料的基石。本文系統整理 stat、fstat、lstat 三大系統呼叫,並深入剖析 struct stat 結構體中的檔案類型、權限位元、時間戳記、連結計數等核心欄位,附完整 C 語言範例與實測輸出,助你從核心視角掌握檔案元資料。

一、取得檔案屬性:stat 族群

#include 
#include 

int stat(const char *pathname, struct stat *buf);   // 依路徑取得,追蹤符號連結
int fstat(int fd, struct stat *buf);                // 依檔案描述符取得
int lstat(const char *pathname, struct stat *buf);  // 依路徑取得,不追蹤符號連結
// 回傳:成功 0,失敗 -1 (設 errno)

關鍵差異:stat/lstat 接收路徑,fstat 接收已開啟的 fd;lstat 回傳符號連結本身屬性,而非目標檔案。

二、struct stat 核心欄位詳解

struct stat {
    mode_t  st_mode;    // 檔案類型 + 權限位元
    ino_t   st_ino;     // inode 號
    dev_t   st_dev;     // 所在裝置號
    nlink_t st_nlink;   // 硬連結數
    uid_t   st_uid;     // 擁有者 UID
    gid_t   st_gid;     // 群組 GID
    off_t   st_size;    // 檔案大小 (位元組),普通檔有效
    time_t  st_atime;   // 最後存取時間
    time_t  st_mtime;   // 內容最後修改時間
    time_t  st_ctime;   // 狀態 (權限/擁有者/內容) 最後變更時間
};

ls -l 即是呼叫 stat() 後格式化輸出。

三、檔案類型判斷 (st_mode)

st_mode 同時編碼類型與權限。POSIX 定義判斷巨集:

巨集檔案類型ls -l 首字元
S_ISREG()普通檔案-
S_ISDIR()目錄d
S_ISBLK()區塊特殊檔 (硬碟等)b
S_ISCHR()字元特殊檔 (終端、序列埠)c
S_ISFIFO()命名管道 (FIFO)p
S_ISSOCK()Sockets
S_ISLNK()符號連結l

四、實戰範例:檔案類型掃描器

#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    struct stat sb;
    const char *type;
    for (int i = 1; i < argc; i++) {
        if (lstat(argv[i], &sb) == -1) {
            fprintf(stderr, "%s: lstat error\n", argv[i]);
            continue;
        }
        if (S_ISREG(sb.st_mode)) type = "regular";
        else if (S_ISDIR(sb.st_mode)) type = "directory";
        else if (S_ISCHR(sb.st_mode)) type = "char special";
        else if (S_ISBLK(sb.st_mode)) type = "block special";
        else if (S_ISLNK(sb.st_mode)) type = "symlink";
        else if (S_ISFIFO(sb.st_mode)) type = "fifo";
        else if (S_ISSOCK(sb.st_mode)) type = "socket";
        else type = "unknown";
        printf("%s → %s\n", argv[i], type);
    }
    return 0;
}

編譯測試:

$ gcc file_type.c -o file_type
$ ./file_type /dev/initctl /etc/passwd /dev/sda /dev/tty /dev/log /dev/cdrom
/dev/initctl → fifo
/etc/passwd → regular
/dev/sda → block special
/dev/tty → char special
/dev/log → socket
/dev/cdrom → symlink

五、檔案權限與特殊位元

  • 基本權限:rwx (owner/group/other),對應 st_mode 低 9 位。
  • Set-UID (S_ISUID):執行時以檔案擁有者權限運行 (如 passwd)。
  • Set-GID (S_ISGID):執行時以檔案群組權限運行;目錄上設定則新建檔案繼承該群組。
  • Sticky Bit (S_ISVTX):目錄上防止非擁有者刪除檔案 (如 /tmp)。

相關系統呼叫:

  • umask(mode_t mask):設定預設權限遮罩。
  • chmod/fchmod/fchmodat:修改權限。
  • chown/fchown/lchown/fchownat:修改擁有者/群組。

六、時間戳記與 utime/utimensat

  • st_atime:read()、stat() 更新。
  • st_mtime:write()、truncate() 更新。
  • st_ctime:chmod()、chown()、link()、unlink()、write() 更新。

現代程式建議使用 utimensat() (支援奈秒精度) 替代舊有 utime()/utimes()。

結語

熟稔 stat 族群與 struct stat,即能編寫健壯的檔案系統工具、備份軟體、安全稽核腳本。下一步可探討 inotify 監控檔案變更、fanotify 全系統存取審計等進階主題。

Copyright © Windows教程網 All Rights Reserved