登录过程
首先,快速了解一下 shell。Shell 只是一个像其他任何程序一样的程序,它读取您键入的字符,并查找具有相同名称的程序。程序名称在提示符下键入,并由 shell 执行。在命令行末尾添加 & 字符会导致命令在后台运行。
shell 分两个步骤运行程序。首先,shell 执行一个名为“fork”的操作。Forking 创建一个看起来与原始进程完全相同的新进程,继承其父进程的许多属性,例如任何打开的文件和用户 ID。虽然它是 shell 程序的精确副本,但“子”进程不读取用户命令。子 shell 立即执行一个名为“exec”的操作,它是“execute(执行)”的缩写,其中它使 Linux 内核将新程序加载到子 shell 之上,并在其位置运行该程序。
此时,原始 shell 只是等待子程序完成。完成后,它从用户那里获取下一行输入,然后重复整个过程。在一个活跃的 UNIX 系统中,这种事情一直在发生。即使在相当不活跃的系统上,进程仍然在运行以执行内务处理,而其他进程只是在休眠并等待某些事情发生。
从 bash shell 中,您可以通过键入以下内容来查看 exec 的工作原理
exec ls -l
ls 命令像往常一样运行,但是当它完成时,您不再处于登录状态。Shell 被 ls 替换,当它完成时,就好像您的 shell 已经完成一样。
当内核首次加载到内存中时,它会初始化自身以及可能连接到计算机的任何硬件。一旦内核建立到足以运行程序,它就会这样做。第一个程序称为“init”;它的工作是充当所有进程的祖先。
当 init 启动时,它会读取一个名为 inittab 的文件,通常位于 /etc 中。此文件告诉 init 哪些程序应在哪些条件下运行。Init 不仅运行启动系统其余部分的启动脚本,而且还负责关闭系统。
init 的职责之一是运行允许用户登录系统的程序。对于终端(或虚拟控制台),使用的两个程序是 getty 和 login。getty 是“get terminal(获取终端)”的缩写。一个基本的 getty 程序打开终端设备,初始化它,打印 login: 并等待用户名的输入。现代的 getty 程序(Linux 上有几个可用)也可以做其他事情——如果终端设备是(最近的)调制解调器,它们可以读取调制解调器发送的状态代码,以判断呼叫是语音还是传真,并适当处理呼叫。但是,在大多数情况下,人们只是想登录,因此 getty 执行 login 程序,通过命令行给出要登录的用户名。
login 程序然后提示用户输入密码。如果密码错误,login 只会退出。然后 init 进程注意到它的一个子进程已退出,并在相关的终端上生成另一个 getty 进程。如果密码正确,login 将其进程用户 ID 更改为该用户的用户 ID,并执行用户的 shell。此时,用户可以键入命令。当用户通过键入 shell 内置的 logout 命令退出时,shell 退出,init 注意到它的子进程已退出,并在终端上生成另一个 getty。
为什么使用两个单独的程序来登录,而不是仅仅一个?答案是这样做提供了更大的灵活性。例如,getty 不必执行 login——它可以执行一个程序来接收(或发送)传真、一个 PPP 守护程序来模拟串行线路上的网络连接,或者如果您有一个带有“语音信箱”的调制解调器,则可以执行那些人们非常讨厌的电话树程序之一(“按五键再次收听这些选项”)。
类似地,有时在没有 getty 的情况下也需要 login;例如,当用户通过网络登录时,没有终端设备在等待。相反,每个新连接都由一个名为 telnetd 的程序处理,该程序会 fork 并执行 login 进程。telnetd 保持在网络和新 shell 之间传递字符。
作为该过程如何工作的部分示例,列表 1 显示了 getty 的 autologin 替代品。此替代品适用于那些厌倦了无数次键入其用户 ID 和密码的人。您可以启动 Linux 并使其直接进入几个 shell——有点像 DOS,但带有虚拟控制台。
要安装 autologin,请将其复制到 /sbin(系统二进制文件)目录并键入
chmod +x /sbin/autologin
作为 root 用户。仍然以 root 用户身份,编辑 /etc/inittab 文件并更改如下所示的行
c1:12345:respawn:/sbin/getty 38400 tty1
改为
c1:12345:respawn:/sbin/autologin tty1 login -f myid
将 myid 替换为您自己的用户 ID。Red Hat 安装通常在行首没有字母 c。
请务必保留一些包含 getty 的行,就像它们现在这样——如果您做错了什么,您将需要一种登录系统的方法。在我自己的系统上,我更改了 c1 到 c3,并运行了三个初始 shell。一旦文件被编辑,重新启动系统,一切都应该正常工作。
autologin 的第一个参数是终端的名称。命令行其余部分用作执行工作的登录命令。
第一行告诉内核如何运行此程序,在本例中是通过让 bash shell 解释它。第一个 exec 行是 Bourne shell 技巧,它允许 shell 脚本更改其标准输入、标准输出和标准错误的源/目标。我们希望将文件描述符 0、1 和 2 设置为引用终端设备,这是 login(和许多其他程序)运行时所期望的。cat 命令显示系统的标准登录消息。shift 命令移动 shell 脚本的位置参数。参数 $1 被删除,参数 $2 变为 $1,参数 $3 变为 $2,依此类推。最后一行将命令行的其余部分作为程序执行。在本例中,login -f 选项执行正常的登录过程,-f 选项告诉 login 不要麻烦密码。
