Blog Details

Linux 作業系統 cutexyz > Blog > 學習 Linux > 新手村 > stat 查看檔案完整的異動時間搓

stat 查看檔案完整的異動時間搓

stat filename.txt

執行後會條列出如下資訊:

  • Access: (atime)
  • Modify: (mtime)
  • Change: (ctime)
  • Birth: (檔案創建時間,僅部分現代檔案系統支援)
時間縮寫 全名 代表意義 常用查看指令
mtime Modification Time 內容修改時間。當檔案內容(data)被變更時更新。 ls -l
ctime Change Time 狀態改變時間。當檔案屬性(metadata,如權限、擁有者、檔名)變更時更新。 ls -lc
atime Access Time 讀取存取時間。當檔案被讀取(如 cat 或執行)時更新。 ls -lu

什麼動作會改變什麼時間?

假設你有一個檔案叫 test.txt

  • 當你執行 cat test.txt
    • 只有 atime 會更新(因為你只是「讀取」,沒改內容也沒改屬性)。
  • 當你執行 chmod 777 test.txt
    • 只有 ctime 會更新(因為你改了「權限」,這是屬性變更,但內容沒變)。
  • 當你執行 vi test.txt 並增加一行字:
    • mtime 更新(內容變了)。
    • ctime 也會更新(因為內容變了,檔案大小 size 隨之改變,屬性也算變了)。
  • 當你搬移檔案 mv test.txt backup.txt
    • ctime 更新(檔名變更也是一種屬性改變)。

如何來修改檔案的相關時間戳

Linux 中最常被用來「操控」檔案時間的指令:touch。雖然 touch 的字面意思是「碰一下」,但它真正的強項在於修改檔案的時間戳記,或者在檔案不存在時直接建立一個空檔案

  1. 使用 touch 修改時間的常見招式
    • 一般操作: 如果你執行 touch file.txt,它會同時將 atimemtime 更新為「現在時間」。
    • 只改存取時間 (atime): touch -a file.txt
    • 只改修改時間 (mtime):touch -m file.txt
    • 「偽造」成過去或未來的一個特定時間:
      • 如果你想讓檔案看起來像是在 2025 年 10 月 12 日早上 10 點 30 分改的請執行以下指令
      • touch -t 202510121030 file.txt
    • 參考另一個檔案的時間: 想讓 file_A 的時間跟 file_B 一模一樣?
      • touch -r file_B file_A
  2. 需要修改檔案時間的原因是什麼?
    • 以下列出幾個正當原因
      • 騙過編譯工具 (如 Makefile):make 這樣的工具會比較 .c 原始碼跟 .o 編譯檔的時間。如果原始碼的時間比編譯檔新,它就會重新編譯。有時候你只是改了個註解不想重新編譯,就可以用 touch 把編譯檔的時間「刷」新。
      • 觸發排程工作: 有些備份腳本或自動化程式會檢查「過去 24 小時內有變動的檔案」。如果你想手動讓某個舊檔案被納入備份,touch 一下是最快的方法。
      • 建立預留檔案: 在寫程式測試檔案上傳或權限時,先用 touch 生出一個 0 KB 的空檔案來測試路徑是否正確。
  3. 但有一個不可抹滅的紀錄:ctime 的特殊性
    • 這裡有一個 Linux 檔案系統的「誠實機制」:你無法直接用 touch 修改 ctime (Change Time)。
    • 為什麼? 因為 ctime 是由核心(Kernel)控制的,只要檔案的 metadata(屬性、權限、甚至時間戳記本身)被改動,ctime 就會自動更新為「當下改動的那一刻」。
    • 隱含意義: 如果一個檔案的 mtime 是昨天的,但 ctime 是剛才,這通常代表有人動過這個檔案的權限、換過檔名,或者是用 touch 刻意去改過 mtime。這在資安追蹤時是一個很重要的線索。
  4. 練習一下
touch demo.txt (建立檔案)

stat demo.txt (觀察原始時間)

touch -t 202001011200 demo.txt (改成六年前)

ls -l demo.txt (你會發現時間顯示變成了 2020)

stat demo.txt (你會發現 mtime 變成了 2020,但 ctime 卻顯示為現在!)

Leave A Comment

All fields marked with an asterisk (*) are required