Init

**init**（為英語：initialization 的簡寫）是 Unix 和 類 Unix 系統中用來產生其它所有行程的程式。它以守護行程的方式存在，其行程號為 1。Linux 系統在啟動時載入 Linux 核心後，便由 Linux 核心載入 init 程式，由 init 程式完成餘下的啟動過程，比如載入執行級別，載入服務，啟動 Shell / 圖形化介面等等。

Unix 系列中 (如 System III 和 System V)**init** 的作用，和研究中的 Unix 和 BSD 衍生版本相比，發生了一些變化。大多數 Linux 發行版是和 System V 相容的，但是一些發行版如 Slackware 採用的是 BSD 風格，其它的如 Gentoo 是自己客製化的。後來 Ubuntu 和其他一些發行版採用 Upstart 來代替 傳統的 init 處理程式。至 2015 年，大部分 Linux 發行版都已採用新的 systemd 替代 System V 和 Upstart，但 systemd 向下相容 System V。

## BSD 風格

BSD init 執行存放於 '/etc/rc' 的初始化 shell 指令碼，然後啟動基於文字模式的終端 (getty) 或者基於圖形介面的終端 (窗口系統，如 X)。 這裡沒有執行模式的問題，因為檔案 'rc' 決定了 init 如何執行。

_優點:_ 簡單且易於手動編輯。

_缺點:_ 如果第三方軟體需要在啟動過程執行它自身的初始化指令碼，它必須修改已經存在的啟動指令碼，一旦這種過程中有一個小錯誤，都將導致系統無法正常啟動。

值得注意的是，現代的 BSD 衍生系統一直支援使用 'rc.local' 檔案的方式，它將在正常啟動過程接近最後的時間以子指令碼的方式來執行。這樣做減少了整個系統無法啟動的風險。然後，第三方軟體套件可以將它們獨立的 start/stop 指令碼安裝到一個原生的 'rc.d' 目錄中 (通常這是由 ports collection/pkgsrc 完成的)。 FreeBSD 和 NetBSD 現在預設使用 **rc.d** ，該目錄中所有的使用者啟動指令碼，都被分成更小的子指令碼，和 SysV 類似。**rcorder** 通常根據在 **rc.d** 目錄中指令碼之間的依賴關係來決定指令碼的執行順序。

## SysV 風格

System V init 檢查 '/etc/inittab' 檔案中是否含有 'initdefault' 項。這告訴 init 系統是否有一個預設執行模式。如果沒有預設的執行模式，那麼使用者將進入系統控制台，手動決定進入何種執行模式。

### 執行模式

System V 中執行模式描述了系統各種可能的狀態。通常會有 8 種執行模式，即執行模式 0 到 6 和 _S_ 或者 _s_。其中執行模式 3 為 "保留的" 執行模式：

* 0. 關機
* 1. 單使用者模式
* 6. 重新啟動

除了模式 0,1,6 外，每種 Unix 和 Unix-like 系統對執行模式的定義不太一樣。通常在 /etc/inittab 檔案中定義了各種執行模式的工作範圍。

目前絕大多數 Linux 發行版已經基於新的 systemd，systemd 一般不再使用 /etc/inittab 檔案，也使用新的 target 取代 System V 的執行等級，但仍然相容 System V 的執行等級。若要設定系統預設的執行模式，需要使用 systemctl default targetname.target 命令。

### 預設的執行模式

上面的表中有兩種 Linux 發行版預設的執行模式為 5，模式 5 是多使用者圖形環境 (X Window System)，通常還包括 X 顯示管理器。然而在 Solaris 作業系統中，模式 5 被保留用來執行關機和自動切斷電源。

大多數作業系統的使用者可以用下面的命令來判斷當前的執行模式是什麼：

在 root 權限下，執行 telinit 或者 init 命令可以改變當前的執行模式。 /etc/inittab 檔案中設定的預設的執行模式在 :initdefault: 項中。

## 跳過 init

Linux 系統中，現代的 bootloader (如 LILO 或者 GRUB)，使用者可以在初始化過程中最後啟動的行程來取代預設的 `/sbin/init`。

通常是在 bootloader 環境中通過執行 `init=/foo/bar` 命令。例如，如果執行 `init=/bin/bash`，啟動單使用者 root 的 shell 環境，無需使用者密碼。

BSD 的變種，大多數平台，bootstrap 程式是可以被打斷的，然後執行 `boot -s` 命令進入單使用者模式。

單使用者模式並不沒有跳過 init，它仍然可以執行 `/sbin/init`，但是它將使 init 詢問 `exec()` 將要執行的命令 (預設為 `/bin/sh`) 的路徑，而不是採用正常的多使用者啟動順序。如果核心啟動時在 `/etc/ttys` 檔案中被標註為 "不安全"(在某些系統中，當前的 "安全模式" 可能會有些變化)，在允許這種情況 (或者回退到單使用者模式，如果使用者執行 `CTRL+D`)，init 將首先詢問 root 使用者的密碼。 
如果該程式登出，核心將在多使用者模式下重新執行 init。如果系統從多使用者模式切換到單使用者模式，還將碰到上述的情況。

如果核心載入後，init 不能被正常啟動，這將導致 panic 錯誤，此時系統將不可使用。想要通過 init 自身來改變 init 的路徑，不同的版本情況不太一樣 (NetBSD 中可執行 `boot -a`；FreeBSD 中利用 `init_path` 命令裝載變數)。

## 其他風格

很多人一直努力地從某些方面改進傳統的 init 守護行程，使它變得更完善。下面列出的是一些改進（排序不分先後）：

* SystemStarter：用來替代 launchd — Apple Mac OS X 開啟行程
* Initng：完全代替 init ，可以非同步開啟行程
* Upstart：完全代替 init ，可以非同步開啟行程，曾由 Ubuntu 等使用
* Service Management Facility：完全代替 / 重新設計 Solaris 啟動 Solaris 10
* runit：跨平台的完全代替 init 可以並列啟動服務
* BootScripts：GoboLinux
* Mudur：用 Python 寫成的 init 替代品， 可以非同步開啟行程，Pardus Linux 發行版
* systemd：完全替代 init，可並列啟動服務，並能減少在 shell 上的系統開銷，相比傳統的 System V 是一大革新，已被大多數 Linux 發行版所使用

下面列出的專案還沒有大範圍的使用：

* eINIT, 完全代替 init ，可以非同步開啟行程，但是完成這個過程可以不使用 shell 指令碼
* _svscan_ 來自 daemontools 被用作 1 號行程 - 似乎將被 runit 替代
* cinit
* twsinit, 部分用 x86 組譯寫成， 只是用來證明一種概念
* minit
* OpenRC，由 Gentoo 客制

## 參考文獻

## 外部連結

* Linux init man page
* FreeBSD init man page （頁面存檔備份，存於網際網路檔案館）
* boot-scripts
* runit （頁面存檔備份，存於網際網路檔案館）
* minit （頁面存檔備份，存於網際網路檔案館）
* rc.d （頁面存檔備份，存於網際網路檔案館）
* busybox（頁面存檔備份，存於網際網路檔案館）
* smf and milestones in Solaris 10（頁面存檔備份，存於網際網路檔案館）
* cinit
* twsinit （頁面存檔備份，存於網際網路檔案館）
* Mudur

## 參見

* pidof 或者 killall5, 從 System V 開始在很多發行版中使用的另一種程式