目錄操作的核心觀念#

在 Linux 中,「你在哪裡」很重要。每個 Shell 工作階段都有一個工作目錄(Working Directory),所有相對路徑的操作都以此為基準。理解路徑與目錄的操作,是檔案管理的第一步。

PATH 環境變數#

當你輸入一個指令時,Shell 不會搜尋整個檔案系統來找它——而是依序搜尋 $PATH 環境變數中列出的目錄。

這就是為什麼同樣一個指令名稱,在不同使用者下可能執行不同的程式——因為各自的 $PATH 不同。也是為什麼自己寫的 script 要用 ./script.sh 執行——因為目前目錄 . 通常不在 $PATH 中(基於安全考量)。

檔案內容查閱的層次#

查閱檔案內容有不同的工具,適用於不同場景:

  • 整檔查閱cat(順向)、tac(逆向)、nl(附加行號)
  • 分頁查閱more(只能往前)、less(可以前後翻頁與搜尋)
  • 部分擷取head(取前 N 行)、tail(取後 N 行)
  • 二進位查閱od(以八進位/十六進位顯示)

tail -f 可以持續追蹤檔案的新增內容,是監看 log 檔的經典用法。在開發和除錯時極為常用。

檔案時間屬性#

Linux 為每個檔案記錄三種時間:

  • mtime(modification time):檔案內容最後被修改的時間。ls -l 預設顯示的就是這個
  • ctime(status change time):檔案屬性(權限、擁有者等)最後被變更的時間
  • atime(access time):檔案最後被讀取的時間

touch 指令的主要用途不是「建立空檔案」(雖然常被這樣使用),而是修改檔案的時間屬性。在建置系統中,touch 常被用來更新檔案的 mtime,觸發 make 等工具的重新編譯判斷。

umask:預設權限的控制#

新建檔案的預設權限由 umask 決定。umask 是一個「遮罩」——它指定哪些權限要被拿掉

  • 新建檔案的基礎權限是 666(沒有 x,因為檔案預設不應該是可執行的)
  • 新建目錄的基礎權限是 777
  • 實際權限 = 基礎權限 - umask

例如 umask 為 022 時:

  • 新檔案:666 - 022 = 644(rw-r–r–)
  • 新目錄:777 - 022 = 755(rwxr-xr-x)

如果 umask 設為 000,所有新建的檔案都會是 666(所有人可讀可寫),這在共用系統上是嚴重的安全隱患。

隱藏屬性與特殊權限#

隱藏屬性(chattr/lsattr)#

除了標準的 rwx 之外,Linux 還有一套隱藏屬性系統,可以對檔案施加額外的保護:

  • i(immutable):檔案完全無法被修改、刪除、改名、建立連結。連 root 都不行
  • a(append only):只能追加內容,不能修改或刪除。適合 log 檔

特殊權限:SUID、SGID、SBIT#

這三個特殊權限解決了普通 rwx 無法處理的場景:

  • SUID(Set UID):執行時暫時取得檔案擁有者的權限。經典案例:passwd 指令讓一般使用者能修改 /etc/shadow
  • SGID(Set GID):執行時取得檔案群組的權限;用在目錄上時,新建的檔案會自動繼承該目錄的群組
  • SBIT(Sticky Bit):用在目錄上,確保使用者只能刪除自己的檔案。經典案例:/tmp 目錄

SUID 是一個強大但危險的機制。如果一個 SUID 程式有安全漏洞,攻擊者就可以用它取得 root 權限。定期檢查系統中的 SUID 檔案是安全稽核的基本項目。

檔案搜尋#

指令搜尋#

  • which:在 $PATH 中搜尋指令的位置
  • type:判斷指令是內建指令還是外部程式

檔案搜尋#

  • whereis:只搜尋特定目錄(速度快)
  • locate:從預建的資料庫中搜尋(速度極快,但資料庫可能不是最新的)
  • find:即時搜尋整個檔案系統(功能最強大,但速度最慢)

日常使用優先用 locate(快),找不到再用 find(全面)。locate 的資料庫通常每天自動更新一次,如果要搜尋剛建立的檔案,需要先手動執行 updatedb

權限與指令的實務對應#

理解權限最好的方式是思考「要完成某個操作,需要哪些權限」:

操作所需權限
進入目錄目錄的 x
列出目錄內容目錄的 r + x
讀取檔案目錄的 x + 檔案的 r
修改檔案目錄的 x + 檔案的 r + w
建立新檔案目錄的 w + x
刪除檔案目錄的 w + x(與檔案本身的權限無關)