Linux系统启动时究竟按什么顺序执行哪些程序?这一秘密就隐藏在/etc/inittab文件中。简单来说,该文件负责控制Linux启动时程序的先后顺序,并指定系统默认进入的运行级别。当然,现代CentOS系统已逐步迁移至systemd,但在传统的SysV init体系里,inittab充当着启动流程总指挥的角色。
运行级别(run-level)是怎么回事
运行级别本质上是系统状态的一种标志。RHS(Red Hat系列)定义了6个级别,每个级别对应不同的服务组合:
- 0 — 停机。切勿将默认运行级别设为0,否则开机即关机,谁也受不了。
- 1 — 单用户模式。相当于Windows的安全模式,常用于系统修复或密码恢复。
- 2 — 多用户模式,但不支持NFS。如果没有网络需求,该级别与级别3基本相同。
- 3 — 完全多用户模式。标准的文本模式(text mode),大部分服务器默认使用此级别。
- 4 — 保留未用。
- 5 — X11模式,即图形界面模式。
- 6 — 重启。同级别0一样,不要设为默认值。
问题来了:inittab文件中的有效语句遵循什么格式?答案是四段式:id:runlevels:action:process。
四个字段各自的含义
id:标识名,最多4个字符,同一文件中不可重复。你可以随意命名,但不要超长,也不能冲突。
runlevels:表示该行适用于哪些运行级别。例如想同时支持1、2、3级别,可写成123。注意:sysinit、boot、bootwait这三个action会忽略此设置——它们无论运行级别是多少都会执行。
action:此字段最值得细看,它决定了init进入对应运行级别时如何执行process字段指定的命令。常用值包括:
- respawn:init会持续监控该进程,即使其结束,也会立即重新启动。类似于守护进程的看门狗。
- wait:执行一次,并且init会等待它结束才进行下一步操作。具有清晰的先后依赖关系。
- once:只执行一次,init不等待,执行完就继续处理其他事情。
- boot:系统启动时自动运行,不受运行级别影响。
- bootwait:系统启动时运行,但init会等待它结束。
- off:实际意义不大,相当于忽略该行。
- initdefault:指定系统启动后的默认运行级别。注意,该行不需要process字段,因为它仅用于设定启动时进入哪个运行级别。如果inittab中没有此记录,系统启动时会在控制台询问你要进入哪个级别。
- sysinit:系统启动时准备运行的基础命令,例如清理
/tmp目录。具体可查看/etc/rc.d/rc.sysinit脚本。 - powerwait:电源被切断时,init会执行关闭系统操作。前提是有UPS及监控UPS的软件。RH Linux默认未加入此项。
- powerfail:与powerwait类似,但init不会等待正在运行的进程结束。同样,默认未加入。
- powerokwait:电源恢复时,init需要执行的操作。
- powerfailnow:UPS电池即将耗尽时,init需要执行的操作。与前两个power字段不同,此为紧急状态。
- ctrlaltdel:用户按下Ctrl+Alt+Del时,init重启系统。若系统置于公共场所,可将此组合键改为其他行为,例如忽略或打印警告。(有资深工程师将其改成了一句玩笑话^o^)
- kbrequest:监视特定键盘组合键时触发,目前尚不完善。
- ondemand:标记为ondemand的进程,会在指定的ondemand运行级别被调用时执行,但不会真正切换运行级别。ondemand级别的标记为
a、b、c。
process:即要执行的程序路径或命令。
举两个实例
id:3:initdefault: — 表示系统启动后默认进入命令行模式。
x:5:once:/etc/X11/prefdm -nodaemon — 表示进入X11模式时,执行一次prefdm -nodaemon。
实战经验
最实用的场景:想开机直接进入命令行模式,就编辑/etc/inittab文件,设置为id:3:initdefault:;想直接进入图形界面,就改成id:5:initdefault:。改完后保存重启,系统便会按新级别启动。再次提醒:千万不要设置成0或6。
说到最后,虽然现代Linux已逐步用systemd替代了传统的init,但理解inittab的工作原理,仍然是深入掌握Linux启动过程的重要基础。毕竟,懂得老地图的绘制方式,才能看懂新地图上的路标。
