在 Linux 系统中,执行级别 run level 是指运维的级别,用于描述一种表明什么服务是可用的系统执行状态。
执行级别 1 是严格限制的,仅仅用于系统维护;该级别下,互联网连线将不可操作,但是管理员可以通过控制台连线登入系统。
其他执行级别的系统允许任何人登入和使用,但是不同级别中可使用的服务不同。本文将探索如何配置执行级别,如何互动式改变系统执行级别以及修改该状态下可用的服务。
Linux 系统的预设执行状态是一个在系统开机时使用的执行级别(除非有其他的指示),它通常是在 /etc/inittab 档案中进行配置的,该档案内容通常如下:

id:3:initdefault

包括 Debian 系统在内的一些系统,预设执行级别为 2,而不是上述档案中的 3,甚至都没有 /etc/inittab 档案。
执行级别在预设情况下是如何被配置,其配置依赖于你所执行的 Linux 操作系统的具体发行版本。 例如,在某些系统中, 执行级别 2 是多使用者模式,执行级别 3 是多使用者模式并支援 NFS(互联网档案系统)。 在另外一些系统,执行级别 2 – 5 基本相同,执行级别 1 是单使用者模式。例如,Debian 系统的所用执行级别如下:

0 = 停机
1 = 单使用者(维护模式)
2 = 多使用者模式
3-5 = 同 2 一样
6 = 重启

在 Linux 系统上,执行级别 3 用于共享档案系统给其它系统,可以方便地只通过改变系统的执行级别来启动和停止档案系统共享。系统从执行级别 2 改变到 3 系统将允许档案系统共享,反之从执行级别 3 改变到 2 则系统不支援档案系统共享。
在某个执行级别中,系统执行哪些程序依赖于目录 /etc/rc?.d 目录的内容,其中 ? 可以是 2 、 3 、 4 或 5(对应于相应的执行级别)。
在以下示例中(Ubuntu 系统),由于这些目录的配置是相同的,我们将看见上述 4 个级别对应的目录中的内容是一致的。

/etc/rc2.d$ ls
README S20smartmontools S50saned S99grub-common
S20kerneloops S20speech-dispatcher S70dns-clean S99ondemand
S20rsync S20sysstat S70pppd-dns S99rc.local
/etc/rc2.d$ cd ../rc3.d
/etc/rc3.d$ ls
README S20smartmontools S50saned S99grub-common
S20kerneloops S20speech-dispatcher S70dns-clean S99ondemand
S20rsync S20sysstat S70pppd-dns S99rc.local
/etc/rc3.d$ cd ../rc4.d
/etc/rc4.d$ ls
README S20smartmontools S50saned S99grub-common
S20kerneloops S20speech-dispatcher S70dns-clean S99ondemand
S20rsync S20sysstat S70pppd-dns S99rc.local
/etc/rc4.d$ cd ../rc5.d
/etc/rc5.d$ ls
README S20smartmontools S50saned S99grub-common
S20kerneloops S20speech-dispatcher S70dns-clean S99ondemand
S20rsync S20sysstat S70pppd-dns S99rc.local

这些都是什么档案?它们都是指向 /etc/init.d 目录下用于启动服务的指令码符号连线。 这些档案的档名是至关重要的, 因为它们决定了这些指令码档案的执行顺序,例如, S20 指令码是在 S50 指令码前面执行的。

$ ls -l
total 4
-rw-r–r– 1 root root 677 Feb 16 2016 README
lrwxrwxrwx 1 root root 20 Aug 30 14:40 S20kerneloops -> ../init.d/kerneloops
lrwxrwxrwx 1 root root 15 Aug 30 14:40 S20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root 23 Aug 30 16:10 S20smartmontools -> ../init.d/smartmontools
lrwxrwxrwx 1 root root 27 Aug 30 14:40 S20speech-dispatcher -> ../init.d/speech-dispatcher
lrwxrwxrwx 1 root root 17 Aug 31 14:12 S20sysstat -> ../init.d/sysstat
lrwxrwxrwx 1 root root 15 Aug 30 14:40 S50saned -> ../init.d/saned
lrwxrwxrwx 1 root root 19 Aug 30 14:40 S70dns-clean -> ../init.d/dns-clean
lrwxrwxrwx 1 root root 18 Aug 30 14:40 S70pppd-dns -> ../init.d/pppd-dns
lrwxrwxrwx 1 root root 21 Aug 30 14:40 S99grub-common -> ../init.d/grub-common
lrwxrwxrwx 1 root root 18 Aug 30 14:40 S99ondemand -> ../init.d/ondemand
lrwxrwxrwx 1 root root 18 Aug 30 14:40 S99rc.local -> ../init.d/rc.local

如你所想,目录 /etc/rc1.d 因执行级别 1 的特殊而不同。它包含的符号连结指向非常不同的一套指令码。 同样也要注意到其中一些指令码以 K 开头命名,而另一些与其它执行级别指令码一样以 S 开头命名。这是因为当系统进入单使用者模式时, 一些服务需要停止。 然而这些 K 开头的符号连结指向了其它级别 S 开头的符号连结的同一档案时, K(kill)表示这个指令码将以指示其停止的引数执行,而不是以启动的引数执行。

/etc/rc1.d$ ls -l
total 4
lrwxrwxrwx 1 root root 20 Aug 30 14:40 K20kerneloops -> ../init.d/kerneloops
lrwxrwxrwx 1 root root 15 Aug 30 14:40 K20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root 15 Aug 30 14:40 K20saned -> ../init.d/saned
lrwxrwxrwx 1 root root 23 Aug 30 16:10 K20smartmontools -> ../init.d/smartmontools
lrwxrwxrwx 1 root root 27 Aug 30 14:40 K20speech-dispatcher -> ../init.d/speech-dispatcher
-rw-r–r– 1 root root 369 Mar 12 2014 README
lrwxrwxrwx 1 root root 19 Aug 30 14:40 S30killprocs -> ../init.d/killprocs
lrwxrwxrwx 1 root root 19 Aug 30 14:40 S70dns-clean -> ../init.d/dns-clean
lrwxrwxrwx 1 root root 18 Aug 30 14:40 S70pppd-dns -> ../init.d/pppd-dns
lrwxrwxrwx 1 root root 16 Aug 30 14:40 S90single -> ../init.d/single

你可以改变系统的预设执行级别,尽管这很少被用到。例如,通过修改前文中提到的 /etc/inittab 档案,你能够配置 Debian 系统的预设执行级别为 3(而不是 2),以下是该档案示例:

id:3:initdefault:

一旦你修改完成并重启系统, runlevel 命令将显示如下:

$ runlevel
N 3

另外一种可选方式,使用 init 3 命令,你也能改变系统执行级别(且无需重启立即生效), runlevel 命令的输出为:

$ runlevel
2 3

当然,除非你修改了系统预设级别的 /etc/rc?.d 目录下的符号连结,使得系统预设执行在一个修改的执行级别之下,否则很少需要通过建立或修改 /etc/inittab 档案改变系统的执行级别。
在 Linux 系统中如何使用执行级别?
为了扼要重述在系统中如何使用执行级别,下面有几个关于执行级别的快速问答问题:
如何查询系统当前的执行级别?
使用 runlevel 命令。
如何检视特定执行级别所关联的服务程序?
检视与该执行级别关联的执行级别开始目录(例如, /etc/rc2.d 对应于执行级别 2)。
如何检视系统的预设执行级别?
首先,检视 /etc/inittab 档案是否存在。如果不存在,就执行 runlevel 命令查询,你一般就已经处在该执行级别。
如何改变系统执行级别?
用 init 命令(例如 init 3)临时改变执行级别,通过修改或建立 /etc/inittab 档案永久改变其执行级别。
能改变特定执行级别下执行的服务么?
当然,通过改变对应的 /etc/rc?.d 目录下的符号连线即可。
还有一些其他的什么需要考虑?
当改变系统执行级别时,你应该特别小心,确保不影响到系统上正在执行的服务或者正在使用的使用者。