/etc/inittab 文件控制着初始化过程。
/etc/inittab 文件为 init 命令提供脚本作为一个普通进程调度程序。构成 init 命令进程调度活动的主要(多数)进程是 /etc/getty 线进程(line process),发起(启动)专用线进程。被 init 命令特别调度的其他进程为后台进程(Daemon)和shell。
/etc/inittab 文件由 位置相关[position-dependent ]的条目组成,格式如下:
Identifier:RunLevel:Action:Command
每一个条目都被一个换行字符分隔。一个换行字符前面一个反斜杠 (\) 表示一个条目的延续。/etc/inittab 文件中的条目数目没有限制(而不是指条目的最大长度)。条目的最大长度是 1024 个字符。
条目字段有:
Identifier: 标识唯一对象的一个 1-4 位字符的字段。
RunLevel: 该条目运行的级别。
运行级别有下列属性:
- 运行级别有效地符合系统进程的配置。
- 由 init 命令启动的每一个进程都被分配一个或多个该进程可存在于之的运行级别。
- 运行级别由 0-9 的数字来表示。例如,如果系统运行于级别 1,只有在运行级别字段有 1 的那些条目被启动。
- 请求 init 命令改变运行级别时,条目中运行级别字段与目标运行级别不匹配的所有进程都会收到一条警告信号 (SIGTERM),在进程被删除符号[kill signal (SIGKILL)]强行终止前,有20秒的宽限期。
- 运行级别字段可为一个进程定义多个运行级别,可以0-9的任意组合。如果没有指定运行级别,进程假定在所有的运行级别有效。
- 还有其他四个值会出现在运行级别字段,即使他们并不是真正的运行级别:a, b, c 和 h。在运行级别字段有这些字符的条目仅仅在telinit 命令请求时才运行(与当前的系统运行级别无关)。他们不同于init命令的运行级别,init命令永远不能进入a, b, c, h 运行级别。并且,所有这些进程的运行请求都不改变当前的运行级别。此外,init 命令改变级别时,由a, b, c 命令启动的进程并不断开(killed)。只有当 /etc/inittab 文件中他们的行在action字段标记为 off,他们的行从 /etc/inittab 文件中完全删除,或者init 命令进入单用户模式,这些进程才会被中断(killed)。
Action: 告知 init 命令如何处理在 process 字段指定的进程。init 命令可识别的 actions 如下:
respawn: 如果进程不存在,则启动进程。却不等待进程终止(继续扫描 /etc/inittab 文件)。如进程死掉,则重启该进程。如进程存在,继续扫描 /etc/inittab 文件。
wait: 当 init 命令进入匹配某条目的运行级别时,启动该进程并等待该进程的终止。当 init 命令处于同样的运行级别时,所有对 /etc/inittab 文件随后的读取都会导致 init 命令忽略该条目。
once: 当 init 命令进入匹配某条目的运行级别时,启动该进程,并且不等待终止。当进程死掉时,也不重启该进程。当系统进入一个新的运行级别时,该进程仍然从之前运行级别的变化运行,程序也不重启。
boot: 只在系统引导过程中运行的条目,这些进程是系统启动过程中,init 命令从 /etc/inittab 文件中读取的。启动该进程,不等待进程终止,并且进程死掉时,也不重启进程。有意义的指导依次为,运行级别应为默认,或者必须与系统引导时 init 命令的运行级别匹配。此 action 对于系统硬件重启后的初始化功能非常有用。
bootwait: 系统引导后,init 命令从单用户到多用户状态,第一次运行的条目。启动该进程,并等其终止,进程死时,不重启该进程。如果 initdefault 为 2 ,则系统引导后直接运行该进程。
powerfail: 只有当 init 命令收到一个电源故障信号(SIGPWR)的时候,才执行与此条目相关的进程。
powerwait: 只有当 init 命令收到一个电源故障信号(SIGPWR)的时候,才执行与此条目相关的进程。并等该进程终止,才继续处理 /etc/inittab 文件。
off: 如果与该条目相关的进程当前正在运行,发送一个警告信号(SIGTERM),然后等待 20 秒才用 kill 信号(SIGKILL)终止该进程。如果进程不在运行,忽略该条目。
ondemand: 功能上与 respawn 相同,不过,此 action 应用 a, b, 或 c 值,而不用运行级别。
initdefault: init 命令只在 最初调用时才扫描与此 action 相关的条目。如果存在,init 命令使用该条目来决定初始进入的运行级别。一般情况下,使用run-level 字段中指定的最高运行级别来作为初始状态。如果运行级别字段为空,则认作0123456789;因此,init 命令进入运行级别 9 。另外,如果 init 命令在 /etc/inittab 文件中找不到 initdefault 条目,则在引导时向用户请求一个初始的运行级别。
sysinit: 此类型的条目在登录前 init 命令正要访问控制台之前被执行。该条目只被用来初始化设备,init 命令可能会针对这些设备询问运行级别。这些条目被执行,并等待完成后才继续。
Command: 可执行的壳(shell)命令。整个 command 字段以 exec 为前缀,并传给一个 forked sh成为 sh -c exec 命令。任何合法的 sh 命令语法都可出现在该字段。并可用 # 插入注释。
getty 命令覆写 /etc/inittab 文件中出现在它之前所有命令的输出。要在引导日志中记录这些命令的输出,可输送这些输出到 alog -tboot 命令。
当 init 命令正在处理 inittab 条目时,stdin, stdout, 和 stderr 这些文件描述符(file descriptors)可能是不可用的。所有写入 stdout 或 stderr 的条目不起作用,除非把输出重定向到一个文件或者到 /dev/console。
下列命令是唯一支持在 /etc/inittab 文件中修改记录的方法:
mkitab: 把记录添加到 /etc/inittab 文件。
lsitab: 列出 /etc/inittab 文件中的记录。
chitab: 修改 /etc/inittab 文件中的记录。
rmitab: 从 /etc/inittab 文件中删除记录。
例如,想在 /etc/inittab 文件中添加一条记录,以运行级别2(run level 2)运行 find 命令并使之一旦完成就再次启动。
1. 运行 ps 命令,只显示包含 find 的进程:
# ps -ef | grep find
root 19750 13964 0 10:47:23 pts/0 0:00 grep find
#
2. 使用 mkitab 命令,在 /etc/inittab 文件中添加一个名为 xcmd 的记录:
# mkitab "xcmd:2:respawn:find / -type f > /dev/null 2>&1"
3. 使用 lsitab 命令显示新记录:
# lsitab xcmd
xcmd:2:respawn:find / -type f > /dev/null 2>&1
#
4. 查看进程:
# ps -ef | grep find
root 25462 1 6 10:56:58 - 0:00 find / -type f
root 28002 13964 0 10:57:00 pts/0 0:00 grep find
#
5. 取消 find 命令进程:
# kill 25462
6. 查看进程:
# ps -ef | grep find
root 23538 13964 0 10:58:24 pts/0 0:00 grep find
root 28966 1 4 10:58:21 - 0:00 find / -type f
#
本例中,由于 action 字段被配置 respawn,故而每一次该命令一完成,一个新进程就会启动。
该进程将继续再生 (re-spawning),除非修改 action 字段,例如:
1. 把记录 xcmd 的 action 字段由 respawn 修改为 once:
# chitab "xcmd:2:once:find / -type f > /dev/null 2>&1"
2. 查看进程:
# ps -ef | grep find
root 20378 13964 0 11:07:20 pts/0 0:00 grep find
root 28970 1 4 11:05:46 - 0:03 find / -type f
3. 取消 find 命令进程:
# kill 28970
4. 查看进程:
# ps -ef | grep find
root 28972 13964 0 11:07:33 pts/0 0:00 grep find
#
要从 /etc/inittab 文件中删除该记录,可使用 rmitab 命令。例如:
# rmitab xcmd
# lsitab xcmd
#
/etc/inittab 条目的次序
/etc/inittab 文件中的基本进程条目次序安装如下:
1. initdefault
2. sysinit
3. Powerfailure Detection (powerfail)
4. Multiuser check (rc)
5. /etc/firstboot (fbcheck)
6. System Resource Controller (srcmstr)
7. Start TCP/IP daemons (rctcpip)
8. Start NFS daemons (rcnfs)
9. cron
10.pb cleanup (piobe)
11.getty for the console (cons)
系统资源控制器 (SRC)必须在 /etc/inittab 文件的开头附近就被启动,因为启动其他的进程需要SRC进程(Daemon)。
由于NFS需要TCP/IP进程(Daemon)才能正常运行,所以TCP/IP进程必须在NFS进程之前被启动。
/etc/inittab 文件中的条目按相互依赖性排序,就是说,如果一个进程(process2)需要另外一个进程(process1)存在才能正常运行,那么在 /etc/inittab文件中,process1的条目应该在process2的条目之前。