系统启动与登录shell
时间:2007-06-03 来源:jackie.niu
1.4 系统启动与登录shell
系统启动时运行的第一个进程是init。每个进程都有一个称为PID的进程标识号。init是第一个进程,所以它的PID是1。init进程初始化系统,启动另一个进程来打开终端线路并设置标准输入(stdin),标准输出(stdout)和标准错误输出(stderr),三者都与终端关联。标准输入通常来自键盘,标准输出和标准错误输出则显示在屏幕上。完成这些设置后,终端上就会出现登录提示。
系统会在用户键入用户名后提示输入口令。程序/bin/login通过检查passwd文件的首个字段来确认用户的身份。如果所键入的用户名存在,它会运行一个密码程序来对所键入的口令进行确认。口令验证通过后,login程序设置初始环境。初始环境是一组定义工作环境的变量,这组变量将传给shell。变量HOME、SHELL、USER和LOGNAME根据passwd文件中的信息进行赋值。HOME被设为用户的主目录,SHELL则被设为登录shell的名字,即passwd文件中的最后一列。USER和LOGNAME被赋值为登录名。还设置了变量search path,常用的工具程序可以在该变量指定的目录中找到。login程序结束时执行它在passwd文件最后一列中找到的程序。这个程序通常是一个shell。如果passwd文件最后一列是/bin/csh,执行的就是C shell。如果是/bin/sh或为空,则执行Bourne shell。如果是/bin/ksh或/bin/pdksh,则执行Korn shell。被执行的shell称为登录shell。
shell启动后,先查找由系统管理员设置的系统级的初始化文件,然后在用户的主目录中查找是否存在对应的shell初始化文件。如果存在,就会执行这些文件。这些初始化文件用于进一步定制用户环境。在执行完这些初始化文件之后,就可以启动窗口界面的开发环境,如CDE、Open Windows或Gnome。接着,将显示一个虚拟桌面,该桌面的显示基于配置、控制台以及显示shell提示符的伪终端,此时shell正处于等待输入状态。
1.4.1 解析命令行
在命令提示符后输入一条命令后,shell会读入这个命令行并对命令行进行解析,将其分解为词,称作token。token之间用空格或制表符分隔,命令行以换行符结尾③。接下来,shell检查第一个词是否为内置命令或磁盘上的可执行程序。如果是内置命令,shell就在自己内部执行它。否则,shell将在路径变量所指的目录中查找这个程序。如果找到了命令的程序,shell就创建一个进程来执行它。之后,shell进入睡眠(或等待)状态直至程序执行完毕。shell会根据需要报告程序的退出状态。此时,屏幕上又会出现命令提示符,整个过程从头开始。命令行的处理顺序如下:
(1) 执行历史命令替代(视情况而定)
(2) 命令行被分解为token(或称“词”)
(3) 更新历史命令(视情况而定)
(4) 引用的处理
(5) 别名替代和函数的定义(视情况而定)
(6) 设置重定向,后台进程和管道
(7) 执行变量替换(如$name,$user等)
(8) 执行命令替换(如`date`代替Today)
(9) 执行称为globbing的文件名替换(如cat abc.??,rm *.c等)
(10) 执行命令
1.4.2 命令类型
命令被执行时,可以是别名、函数、内置命令或磁盘上的一个可执行程序。别名是原有命令的缩写(昵称),可用于C、TC、bash和Korn shell。函数可用于 Bourne shell(在AT&T System V的第2版中引入)、bash和Korn shell。函数是由像独立的例程一样的指令组织起来的一组命令。别名和函数都在shell的内存空间中定义。内置命令是shell的内部程序,而可执行程序则在磁盘上。shell用路径变量在磁盘上定位可执行程序。执行命令前,shell需要创建一个子进程。程序定位和子进程创建都要花一定的时间。执行命令前,shell按如下顺序判定命令类型④:
(1) 别名
(2) 关键字
(3) 函数
(4) 内置命令
(5) 可执行程序
举个例子,如果命令是xyz,则shell先检查xyz是不是一个别名。如果不是,再检查它是不是内置命令或函数。如果都不是,那它肯定是磁盘上的一个可执行程序。接下来shell就要开始查找这个命令的路径以便执行。该过程的说明见图1-2。
图1-2 shell与命令执行过程
备注:我们知道Shell执行命令的过程了,我们应该想象一下自己编写一个简单的shell怎么样?应该怎么入手呢?请各位回去认真思考思考。










