Linux FHS 重點節錄

Linux FHS note

Lau Dai He
20 min readJun 1, 2022

Author:Lau Dai

Date:2021/11/27

此文是依照 Linux Foundation FHS 3.0 做資料整理。

主要依照筆者個人理解方式進行翻譯、整理。若有需要,建議可以直接觀看原文資料。

FHS全文為Filesystem Hierarchy Standard,主要用於三種使用者:

  1. 給獨立軟體供應商開發時,符合FHS規範
  2. 創建符合FHS的系統
  3. 使用者了解與維護符合FHS規範的系統

檔案系統(The Filesystem)

在文件系統中,可以透過2x2矩陣來劃分以及區隔:可分享(Shareable)、不可分享(Unshareable)、靜態(Static)、可變動(Variable)。

舉例來說:user home 屬於可分享,然而 device lock 則不是;而靜態檔案包括二進制檔案(binaries)、函式庫(libraries)、文件(documentation)以及其他在沒有管理權限下無法修改的檔案。

使用者可以將靜態檔案與動態檔案分開儲存,因為靜態檔案可以儲存在 read-only 的裝置上,而且不用像可變動檔案一樣進行排程備份。

官方舉例

根檔案系統(The Root Filesystem)

根檔案系統內必修要有足夠的能力去開機、修復、恢復

The contents of the root filesystem must be adequate to boot, restore, recover, and/or repair the system.

因此根路徑會有應用程式、設定檔、boot loader資訊和其他必要的啟動資料

/usr, /opt和/var

根目錄下,各目錄描述

資料來源:https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s02.html

  • /bin:必要的命令binary檔
  • /boot:boot loader的靜態檔案
  • /dev:裝置檔案
  • /etc:系統設定檔
  • /lib:必要的可分享函式庫與核心模組
  • /media:可移除裝置的掛載點
  • /mnt:檔案系統暫時掛載的掛載點
  • /opt:額外的應用程式安裝位置
  • /run:正在運行的程序資料
  • /sbin:必要的系統binary檔
  • /tmp:暫存檔案
  • /usr:第二個階層(?
  • /var:可變動資料

在此文件中,將詳細說明各個目錄,並將 /usr與/var另外拉出新章節說明。

/home、/lib<qual>、/root都是屬於 Optional 的目錄

/bin : Essential user command binaries (for use by all users)

contains commands that may be used by both the system administrator and by users, but which are required when no other filesystems are mounted (e.g. in single user mode). It may also contain commands which are used indirectly by scripts.

  1. /bin內不能有子目錄
  2. 非必要放入 /bin內的命令檔案都放到 /usr/bin內部
  3. 在目錄中有規定需要的 command binaries

附註:

If /bin/sh is not the POSIX compatible shell command itself, it must be a hard or symbolic link to the real shell command.

/boot : Static files of the boot loader

此目錄包含除了開機時的設定檔、map installer 之外所有的開機會用到的檔案都在此。 /boot內儲存的都是在執行 kernel前 user-mode 可以使用的程式。可以儲存 master boot sectors 與 sector map 檔案。(個人註記:UEFI 啟動時,有所不同,需要讀者另外參照 EFI 啟動相關資料)

  1. 使開機程式 boot loader 協助可以正常運作的程式必須放在 /sbin
  2. 開機時,boot loader 不需加載的設定檔放在 /etc

特別規範:

作業系統的 kernel 必須放在 //boot

某些系統對於 /boot有特別要求的在此不一依列舉

/dev : Device files

放置特殊檔案或者裝置檔案

如果需要手動建立 /dev內的檔案,需要有個 MAKEDEV的命令來建立/dev內的檔案。也需要 MAKEDEV.local為了本地設備檔案。

If required, MAKEDEV must have provisions for creating any device that may be found on the system, not just those that a particular distribution installs.

這句話無法理解

/etc : Host-specific system configuration

/etc目錄階層主要是放置系統的設定檔。它是本地檔案並且用來控制設定軟體使用;它必須是靜態且並非 binary 檔案。

主要推薦存放位置在 /etc目錄底下的子目錄,而非直接儲存在/etc底下。

此目錄要求:

  1. 在此目錄沒有 binaries
  2. 有規定特定的實體目錄或者連結目錄

如果有裝相對應的子系統,這些的實體目錄或連結目錄必須在 /etc當中。

  • X11 Configuration for the X Window system (optional)
  • sgml Configuration for SGML (optional)
  • xml Configuration for XML (optional)

也有檔案規定需要放置在 /etc,細節請看此文件

常見的檔案如:fstab, group, hosts, motd, mtab, passwd, profile等

其中在Ubuntu 20.04中式採用 systemd作為 init,因此是不會看到如 inetd.conf、inittab等檔案。

/etc/opt : Configuration files for /opt

主要是你安裝在/opt的第三方套件的設定檔

/etc/X11 : Configuration for the X Window System (optional)

主要是給 X11 使用的設定擋路徑。當 /user 被掛載成 read-only 時,此目錄必須讓本地可以控制。

xorg.conf X.org 7 之後使用的設定檔

Xmodmap全局 X11 鍵盤設定檔案

  • /etc/sgml : Configuration files for SGML (optional)
  • /etc/xml : Configuration files for XML (optional)
  • 上面這兩個路徑,有興趣的同樣再去翻看文件

xdm之前設定擋路徑在 /usr/lib/X11/xdm,現在則是/etc/X11/xdm。xdm 局部變動資料儲存在/var/lib/xdm

/home : User home directories (optional)

/home 路徑顯然是標準的概念,但並非特殊規範的檔案系統路徑,使用者可能會想把他帳號在不同的地方。因此,程式不該假設有一定有個 /home 路徑而去對它進行訪問。

當要找user的家目錄時,不應該依靠 /etc/passwd,因為使用者資訊可能儲存在 NIS 伺服器,因次你需要 library function 如fgetpwent中的 getpwent, getpwent_r

在許多環境下,已有其他目錄服務比 NIS 更先進、更安全,例如 LDAP 就已經逐漸取代 NIS。wiki

此目錄要求:

當需要在使用者家目錄底下為了程式建立特定的設定檔時,需要以 “.”作為開頭(即 dot file 的意思);若該程式有多個設定檔,則需要以 subdirectory 子目錄方式建立 dot directory 資料夾,但其資料夾內的檔案不該再以“.”作為開頭。

個人舉例:

ls .ssh/
config id_ed25519 id_ed25519.pub id_rsa id_rsa.pub known_hosts

/lib : Essential shared libraries and kernel modules

此目錄包含了開機時所需要用到的 shared libraries 以及在 root filesystems 所需要的 command 檔案。

至少需要下面任一種檔案(可以是檔案或者連結符號)

  • libc.so.*The dynamically-linked C library (optional)
  • ld*The execution time linker/loader (optional)

如果 C 語言的預處理器有安裝,/lib/cpp 必須參照它。

當相對應的子系統安裝時,module 目錄必須在 /lib底下。

module 中存放可載入的 kernel 模組。

/lib<qual> : Alternate format essential shared libraries (optional)

此資料夾目的(待確認)

There may be one or more variants of the /lib directory on systems which support more than one binary format requiring separate libraries.

在32或者64位元的電腦中,此資料夾名稱通常為/lib32、/lib64。

此目錄要求:

如果這類型的目錄有多個類似的,那麼需要與一般的/lib目錄內容相同,除了 /lib<qual>/cpp 這檔案非必要相同。

/media : Mount point for removable media

此目錄的子目錄通常掛載可移除裝置媒體,如:軟碟、光碟、zip disk

在歷史上有許多掛載在根目錄的可移除裝置,如/cdrom、/mnt、/mnt/cdrom。這要會造成根目錄有許多額外的目錄。

下列目錄需在/media目錄下:floppy, cdrom, cdrecorder(CD Writer), zip。當目錄下有多個相同裝置時,需要從數字0開始附加在目錄後方,如:/media/cdrom0/media/cdrom1

/mnt : Mount point for a temporarily mounted filesystem

主要是提供給系統管理者,暫時掛載檔案系統所需要的。此路徑不應該要影響任何程式的運作。

此路徑不應該用來安裝程式,下列句子無法理解。

a suitable temporary directory not in use by the system must be used instead.

/opt : Add-on application software packages

/opt是保留給額外安裝的應用程式

安裝在/opt的套件,其靜態檔案需放在 /opt/<package> 或 /opt<provider>目錄樹上。其差異為 package 表示描述此軟體名稱,而 provider 是依據LANANA註冊的名字。(LANANA 全名為 The Linux Assigned Names And Numbers Authority,Linux 命名空間認証機構)

若是此目錄需要的設定檔,儲存位置於 /etc/opt 路徑。套件中的檔案不能放置在 /opt, /var/opt, /etc/opt 之外。除了特殊目的之特殊檔案,舉例為了讓檔案系統運作正常的檔案,如 device lock file 需要位於 /var/lock,而 device檔案需要位於 /dev。

/root : Home directory for the root user (optional)

雖然 root 帳戶的家目錄可以依照開發者決定,但推薦還是使用此路徑作為root 的家目錄。

如果 root 帳戶的家目錄不在 root分區當中,則有必要在設定在無法找到時,將 root 家目錄設定為 /目錄。

root 帳戶不應作為一般非授權帳戶使用,而需將 root 帳戶作為系統管理者角色。基於此原因,不推薦將mail或者其他應用程式子目錄放置 /root 路徑。當需要 mail 給具有管理權限使用者時,使用 root, postmaster, webmaster 等比較恰當。

/run : Run-time variable data

此目錄結構包含從開機以來,關於作業系統的信息資料。此目錄的資料開機的過程中,需要被清除(removed or truncated as appropriate)。

過去與此目錄相同角色的路徑為 /var/run ,除非有特別註明,不然遷移到/run路徑的程式應該要停止使用 /var/run 路徑。

此目錄要求:

最初放在 /etc的 pid(Process identifier)需要放置在 /etc 中,舉例如:acpi.pid, cron.pid。命名格式為:PID檔案加上名字:<program-pid>.pid

PID 內檔案規格一致,都是使用 ASCII 編碼十進位數字加上換行符號。

作業系統中,維護 Unix-domain sockets 的系統程式也會放在此路徑,或者是適當的子目錄。

/sbin : System binaries

系統管理員或者 root 角色會用到的應用程式會存放在 /sbin, /usr/sbin和/usr/local/bin 路徑。除了 /bin路徑, /sbin 也存放開機、修復、恢復 OS 時所需要的 binary 檔案。本地安裝的系統管理程式應該被安裝至 /usr/local/sbin

此目錄要求:

在/sbin中不能有子目錄。

在/sbin中,需要有 shutdown 命令檔案或連結檔案在此路徑。

至於當安裝相關套件時,哪些檔案需要在此路徑,可參考原文連結

/srv : Data for services provided by this system

此目錄提供此系統架站時(透過service),存放會用到的資料

此路徑主要目的為提供使用者在特定服務中,找到資料存放的位置。以便用來放置 read-only data, writable data 或 script(如cgi script)。如果資料只有特定使用者才有興趣,那應該放在他們的 home 路徑。

目前因為對於 /srv 下面的子目錄還沒有共識,所以在命名上還沒辦法指定如何使用。不應該有任何程式去依照 /srv 或 /srv 下面的子目錄去進行運作,因為不同主機情況下情況都不同。

/tmp : Temporary files

/tmp 目錄為提供程式需要臨時檔案時使用

程式不應該假定在 /tmp 中的檔案可以被保留做使用

IEEE 標準 POSIX.1–2008 列出與之相似的需求

雖然儲存在 /tmp 中的檔案會被以某種方式進行管理與刪除,但建議系統在啟動時刪除 /tmp 中的目錄與檔案

如下文,此規範並非強制,而是根據過往歷史習慣給出的建議。

FHS added this recommendation on the basis of historical precedent and common practice, but did not make it a requirement because system administration is not within the scope of this standard.

/usr Hierarchy

/usr 在檔案系統中,是第 2 重要的部份。/usr 是可分享、唯讀檔案資料。這意味著 /usr 可以在不同兼容 FHS 中是可分享且必然無法被寫入。

任何與主機相關或會隨著時間改變的資訊都儲存在其他地方。

大型軟體不能使用 /usr 下面的子目錄結構。

此目錄要求:

在 /usr 中,需要有下列目錄或目錄連結檔案

  • /usr/bin大部份使用者放置命令檔的地方
  • /usr/lib檔案庫
  • /usr/localLocal hierarchy (empty after main installation)推薦讀此目錄原文
  • /usr/sbin非重要的系統二進制檔案
  • /usr/shareArchitecture-independent data;與系統架構無關的唯讀文件資料檔。如:系統手冊文件、顏色管理等。

可存在目錄:

  • /usr/games 遊戲與教育相關二進制檔案
  • /usr/includeC語言的header檔案
  • /usr/libexec其他程式運行時所需要的二進制檔案
  • /usr/lib<qual>Alternate Format Libraries (optional)
  • /usr/src原始碼

X Windows 系統相關的在 /usr 目錄中是個體制中的例外

直到所有版本都使用/var目錄結構為止之前,下列的目錄會以符號連結(symbolic links)方式存在。

/usr/spool -> /var/spool
/usr/tmp -> /var/tmp
/usr/spool/locks -> /var/lock

當系統不需要上述符號連結時,如果需要的話可以移除。

在 Ubuntu 20.04 中,已經無 /usr/{spool,tmp,spool/locks} 等目錄。

/var Hierarchy

/var contains variable data files. This includes spool directories and files, administrative and logging data, and transient and temporary files.

/var 目錄主要包含可變動性的資料,包含如 spool 目錄與檔案、管理 log 資料與短暫性檔案。

但並非所有資料都是屬於可分享的,如/var/log, /var/lock/var/run都是不可分享的。但/var/mail, /var/cache/man, /var/cache/fonts/var/spool是屬於可分享的。

/var 的主要目的是要讓 /usr 可以以 read-only 方式掛載。

若/var 不能以單獨分區存在,最好將 /var 移除根目錄並放入 /usr分區。

應用程式不能在 /var 目錄內建立目錄,此目錄下需要以系統有影響層級,並與 FHS 組織有進行 mailing list 討論後才加入。

  • /var/account(選擇性):此目錄保留目前使用程序帳戶的log與程序使用的資料
  • /var/cache:暫存(cached)應用程式的資料,此資料會用到大量時間的如 I/O 或計算。應用程式必須可以重新產生或者恢復資料。與 /var/spool內的資料不同,這些暫存資料是可以被刪除的。
  • /var/crash(選擇性):此目錄包含系統故障時的 crash dumps 資料。在此版本 FHS 發佈之時,Linux 不支持此結構,但其他符合 FHS 的系統可能有支援此目錄結構。
  • /var/games(選擇性):任何關於 game 在 /usr 相關的可變動資料應該要放在此目錄。而靜態資料如 help text, levle descriptions 等資料要放在其他目錄如 /usr/share/games。
  • /var/lib:此目錄結構包含與應用程式有關的狀態訊息(state information),此狀態訊息是應用程式運行中與主機運行的資料。使用者不需修改 /var/lib 的配置來修改軟體的設定,而儲存這些資料的目錄不能給一般使用者操作。
  • /var/lock:lock files 應該被儲存在 /var/lock 目錄結構,lock file 是給裝置或其他多個應用程式分享資源,如原本在/usr/spool/locks/usr/spool/uucp的 serial device lock files,現在必須儲存在 /var/lock 中。
  • /var/log:此目錄包含各種 log file,大部分的 log 都寫在此目錄或者其子資料夾。
  1. /var/log/lastlog 紀錄每個使用者最後登入情況
  2. /var/log/messages 紀錄systemd的訊息
  3. /var/log/wtmp 紀錄所有登入登出情況
  • /var/mail(選擇性):mail spool 必須透過此目錄取得每個 <username> 的mail檔案,此 /var/mail 路徑可以是來自其他目錄的鏈結。
  • /var/opt:在 /opt 目錄中儲存 package variable data 的地方,其中/var/opt/<subdir>,subdir 這個目錄名稱是來自 package 在 /opt 中儲存靜態資料的目錄名稱。
  • /var/run:在過去式存放啟動以來的資料,目前此功能以移至 /run 目錄,現在保留是為了與舊系統與軟體保持兼容性。
  • /var/spool:此目錄存放稍候處理的資料。通常在處理後就刪除。
  • /var/tmp:此目錄存放的資料是在系統重新啟動前所保留的資料,因此此目錄資料會比 /tmp 保存來的久一點。在開機啟動時,不會刪除此目錄資料。
  • /var/yp(選擇性):存放 NIS(Network Information Service) variable data。廣為人知的是 Sun Yellow Pages (YP) 需放在此目錄。

Operating System Specific Annex作業系統特定附件

此章節的額外需求只推薦限定在作業系統上面,此段落部份不與前面標準衝突

  1. / : Root directory 在 Linux 系統,如果核心檔案放在 / 目錄,那麼會推薦將其命名為 vmlinuxvmlinuz,這在最近的 Linux source package 已這樣使用。
  2. /bin : Essential user command binaries (for use by all users) 在 Linux 系統中,額外的文件檔放在此目錄如:setserial
  3. /dev : Devices and special files 下列 3 個檔案必須存在 /dev 目錄中, /dev/null、/dev/zero、/dev/tty。(詳情如下補充說明)
  4. /etc : Host-specific system configuration 在Linux系統中,額外的文件檔放在此目錄如:lilo.conf
  5. /proc : Kernel and process information virtual filesystem 在 /prco 檔案系統實際上是 Linux 標準處理程序與系統資訊的方式,而不是 /dev/kmem或其他方式。
  6. /sbin : Essential system binaries 放置檔案系統維護與 bootloader 管理等的檔案。選擇性靜態檔案: ldconfig、sln、ssync。雜項檔案: ctrlaltdel、kbdrate
  7. /sys : Kernel and system information virtual filesystem 一些關於檔案系統中的裝置、驅動、部份kernel等資訊記載的地方。底層架構由特定 Linux kernel 決定,反之則未指定。
  8. /usr/include : Header files included by C programs 在裝了 c 或 c++但並非基於 glibc,需要進行符號鏈結檔案。
 /usr/include/asm -> /usr/src/linux/include/asm-<arch>
/usr/include/linux -> /usr/src/linux/include/linux

9. /var/spool/cron : cron and at jobs 此目錄包含 variable data 的 cron 與 at 程式

※ /dev/null:所有寫入此裝置的資料將會被丟棄,若從此裝置讀取內容將會取得EOF狀態。

※ /dev/zero:此裝置是 0 產生的來源。所有寫入此裝置的資料會被丟棄,從此裝置可以讀取出特定長度的 byte 資料以 0 作為表示。

※ /dev/tty:此裝置表示控制 terminal 裝置的同義詞,一旦此裝置被打開,所有讀寫的資料就像實際在 terminal 裝置控制一樣。

結語

從頭到尾花了 6 個月(2022/06/02初版)才把這 FHS 的部份內容看完,實在是愧對自己。透過了解 FHS 架構,才能對於撰寫程式、尋找檔案的時候,更了解 Linux 規則,也了解 Linux OS 設計之美。

--

--

Lau Dai He

Less is more. 2021/08/01起,主要會紀錄各種技術的精華重點文章,方向可能是Pyhton, Linux, WIndows等都有可能。文章內容精簡為主,搭配少部份的個人情感抒發等。(inspired by 路人甲的世界​-知乎作者)