9.2.Shell命令语言
9.2.1 简单命令简介
1.简单命令的格式
简单命令的格式比较自由,包括命令名字符的个数及用于分隔命令名、选项、各参数间的空格数等,都是任意的。命令的格式如下:
$ Command -option argument list
2.简单命令的分类
(1) 系统提供的标准命令
(2) 用户自定义的命令
3.Shell的种类
(1) Bourne Shell
(2) C Shell
(3) Korn Shell
9.2.2 简单命令的类型
根据简单命令功能的不同,可将它们分成如下五大类:
1.进入和退出系统
(1) 进入系统,也称为注册
(2) 退出系统
2.文件操作命令
(1) 显示文件内容命令cat
(2) 复制文件副本的命令cp
(3) 对已有文件改名的命令mv
(4) 撤销文件的命令rm
(5) 确定文件类型的命令file
3.目录操作命令
(1) 建立目录的命令mkdir(简称md)
(2) 撤销目录的命令rmdir(简称rd)
(3) 改变工作目录的命令cd
4.系统询问命令
(1) 访问当前日期和时间命令date
(2) 询问系统当前用户的命令who
(3) 显示当前目录路径名的命令pwd
9.2.3 重定向与管道命令
1.重定向命令
在Linux系统中,由系统定义了三个文件。其中,有两个分别称为标准输入和标准输出的文件,各对应于终端键盘输入和终端屏幕输出。它们是在用户注册时,由Login程序打开的。这样,在用户程序执行时,隐含的标准输入是键盘输入,标准输出即屏幕(输出)显示。但用户程序中可能不要求从键盘输入,而是从某个指定文件上读取信息供程序使用;同样,用户可能希望把程序执行时所产生的结果数据写到某个指定文件中而非屏幕上。为此,用户必须不使用标准输入、标准输出,而把另外的某个指定文件或设备作为输入或输出文件。
Shell向用户提供了这种用于改变输入、输出设备的手段,此即标准输入与标准输出的重定向。用重定向符“<”和“>”分别表示输入转向与输出转向。
2.管道命令
人们又进一步把重定向思想加以扩充,用符号“|”来连接两条命令,使其前一条命令的输出作为后一条命令的输入。
9.2.4 通信命令
1.信箱通信命令mail
信箱通信是作为在UNIX的各用户之间进行非交互式通信的工具。发信者把要发送的消息写成信件,“邮寄”到对方的信箱中。通常各用户的私有信箱采用各自的注册名命名,即它是目录/usr/spool/mail中的一个文件,而文件名又是用接收者的注册名来命名的。信箱中的信件可以一直保留到被信箱所有者消除为止。mail命令在用于发信时,把接收者的注册名当做参数输入后,便可在新行开始键入信件正文,最后仍在一个新行上,用“.”来结束信件或用“^D”退出mail程序(也可带选项)。接收者也用mail命令读取信件,可使用可选项r、q或p等。其命令格式为:mail
2.对话通信命令write
用这条命令可以使用户与当前在系统中的其他用户直接进行联机通信。由于UNIX系统允许一个用户同时在几个终端上注册,故在用此命令前,要用who命令去查看目标用户当前是否联机,或确定接收者所使用的终端名。命令格式为:write user[ttyname],当接收者只有一个终端时,终端名可缺省。
3.允许或拒绝接收消息的mesg命令
其格式为:mesg[-n][-y]
选项n表示拒绝对方的写许可(即拒绝接收消息);选项y指示恢复对方的写许可,仅在此时双方才可联机通信。
9.2.5 后台命令
有些命令需要执行很长时间,这样,当用户键入该命令后,便会发现自己已无事可做,要一直等到该命令执行完毕,方可再键入下一条命令。这时用户自然会想到应该利用这段时间去做别的事。UNIX系统提供了这种机制,用户可以在这种命令后面再加上“&”号,以告诉Shell将该命令放在后台执行,以便用户能在前台继续键入其他命令,完成其他工作。
在后台运行的程序仍然把终端作为它的标准输出和标准输入文件,除非对它们进行重新定向。其标准输入文件是自动地被从终端定向到一个称为“/dev/null”的空文件中。若shell未重定向标准输入,则shell和后台进程将会同时从终端读入。这时,用户从终端键入的字符可能被发送到一个进程或另一个进程,并不能预测哪个进程将得到该字符。因此,对所有在后台运行的命令的标准输入,都必须加以重定向,从而使从终端键入的所有字符都被送到Shell进程。用户可使用ps、wait及Kill命令去了解和控制后台进程的运行。
9.3.联机命令接口的实现
9.3.1 键盘终端处理程序
1.字符接收功能
为了实现人机交互,键盘终端处理程序必须能够接收从终端输入的字符,并将之传送给用户程序。有两种方式可实现字符接收功能:
(1) 面向字符方式。
(2) 面向行方式。
2.字符缓存功能
为了能暂存从终端键入的字符,以降低中断处理器的频率,在终端处理程序中,还必须具有字符缓存功能。字符缓存功能可采用以下两种方式之一:
(1) 专用缓冲方式。
(2) 公用缓冲方式。
3.回送显示
回送显示(回显)是指每当用户从键盘输入一个字符后,终端处理程序便将该字符送往屏幕显示。
4.屏幕编辑
用户经常希望能对从键盘打入的数据(字符)进行修改,如删除(插入)一个或多个字符。为此,在终端处理程序中,还应能实现屏幕编辑功能,包括能提供若干个编辑键。
5.特殊字符处理
终端处理程序必须能对若干特殊字符进行及时处理,这些字符是:
(1) 中断字符
(2) 停止上卷字符
(3) 恢复上卷字符
9.3.2 MS-DOS解释程序
1.命令解释程序的作用
在联机操作方式下,终端处理程序把用户键入的信息送至键盘缓冲区中保存。一旦用户键入回车符,便立即把控制权交给命令解释程序。显然,对于不同的命令,应有能完成特定功能的命令处理程序与之对应。可见,命令解释程序主要作用是在屏幕上给出提示符,请用户键入命令,然后读入该命令,识别命令,再转到相应命令处理程序的入口地址,把控制权交给该处理程序去执行,并将处理结果送至屏幕上显示。若用户键入的命令有错,而命令解释程序未能予以识别,或在执行终结出现问题时,则应显示出某一出错信息。
(1) 常驻部分
(2) 初始化部分
(3) 暂存部分
3.命令解释程序的工作流程
9.3.3 Shell解释程序
1.Shell命令的特点
前面我们介绍了MS-DOS的命令解释程序,它非常简单。而Shell命令解释程序就复杂得多,这主要是因为Shell命令的类型多而复杂所致。主要表现如下:
(1) 一条命令行中含有多个命令。
(2) 具有不同的分隔符。
2.二叉树结构的命令行树
(1) 命令表型结点
Shell命令解释程序按命令行语句的结构顺序进行检查,每当遇到“;”及“&”分隔符时便为之建立一个命令表型结点,将分隔符左面部分构成该结点的左子树,右面部分构成右子树。例如下面的命令行所构成的命令树如下图所示:
Coomand 1; Command 2; &Command 3
由于每一条命令对应了一个处理进程,故在执行命令树时,对应于每一条命令都需要为之创建一个进程,由此为命令树生成一个对应的进程树。在具体执行时,对于“;”型结点,先递归地执行其左子树,待其左子树执行完后,再执行其右子树。对于“&”型结点,可在启动了左子节点执行后,无须等待它执行完毕,便可转去执行其右子结点。
(2) 管道文件型结点
当Shell命令解释程序遇到管道算符“|”时,先为之建立一个管道文件型结点,再将分隔符左面部分构成该结点的左子树,右面部分构成右子树。例如对下面的命令行所构成的命令如下图所示:
Command 1 | Command 2 | Command 3
(3) 简单命令型结点
对于简单命令,在命令行中仅有一条命令,它是属于可以立即执行的命令,系统无需为它建立二叉树结构的命令行树。
3.Linux命令解释程序的工作流程
在Linux系统中,系统初启后,内核为每个终端建立一个进程,去执行Shell解释程序。它的执行过程基本上按如下步骤进行:
(1) 读取用户有键盘输入的命令行。
(2) 对命令进行分析。
(3) 建立相应的子进程。
(4) 等待子进程完成。
(5) 对于“&”型结点,在其左子结点执行后,直接执行其右子树。
9.4.系统调用的概念和类型
程序接口,是OS专门为用户程序设置的,提供给程序员在编程时使用,也是用户程序获得OS服务的唯一途径。它是由一组系统调用(system call)组成,因而,也可以说,系统调用提供了用户程序和操作系统内核之间的接口。系统调用不仅可供所有的应用程序使用,而且也可供OS自身使用。在每个系统中,通常都有几十条甚至上百条的系统调用,并可根据其功能把它们划分成若干类,每一个系统调用都是一个能完成特定功能的子程序。
9.4.1 系统调用的基本概念
1.系统态和用户态
在计算机系统中设置了两种状态:系统态(或称为核心态)和用户态。在实际运行过程中,处理机会在系统态和用户态间切换。相应地,现代多数OS将CPU的指令集分为特权指令和非特权指令两类。
(1) 特权指令。特权指令是指在系统态运行的指令,它对内存空间的访问范围基本不受限制,不仅能访问用户空间,也能访问系统空间。
(2) 非特权指令。非特权指令是在用户态运行的指令。应用程序所使用的都是非特权指令,它只能完成一般性的操作和任务,不能对系统中的硬件和软件直接进行访问,对内存的访问范围也局限于用户空间。
2.系统调用
在OS中提供系统调用的目的,是使应用程序可以通过它直接调用OS中的相关过程,取得相应的服务。系统调用在本质上是应用程序请求OS内核完成某功能时的一种调用,但它是一种特殊的过程调用,它与一般的过程调用有下述几方面的明显差别:
(1) 运行在不同的系统状态。
(2) 状态的转换。
(3) 返回问题。
(4) 嵌套调用。
3.中断机制
系统调用是通过中断机制实现的,并且一个操作系统的所有系统调用,都通过同一个中断入口来实现。如MS-DOS提供了INT 21H,应用程序通过该中断获取操作系统的服务。
对于拥有保护机制的OS来说,中断机制本身也是受保护的,在IBM PC上,Intel提供了多达255个中断号,但只有授权给应用程序保护等级的终端号,才是可以被应用程序调用的。对于未被授权的中断号,如果应用程序进行调用,同样会引起保护异常,而导致自己被操作系统停止。如Linux仅仅给应用程序授权了4个中断号:3,4,5以及80h。前三个中断号是提供给应用程序调试所使用的,而80h正是系统调用(system call)的中断号。
9.4.2 系统调用的类型
1.进程控制类系统调用
(1) 创建和终止进程的系统调用。
(2) 获得和设置进程属性的系统调用。
(3) 等待某事件出现的系统调用。
2.文件操纵类系统调用
(1) 创建和删除文件。
(2) 打开和关闭文件的系统调用。
(3) 读和写文件的系统调用。
3.进程通信类系统调用
在单处理机系统中:
消息传递方式
共享存储区方式
9.4.3 POSIX标准
目前许多操作系统都提供了上面所介绍的各种类型的系统调用,实现的功能也相类似,但在实现的细节和形式方面却相差很大,这种差异给实现应用程序与操作系统平台的无关性带来了很大的困难。为了解决这一问题,国际标准化组织ISO给出了有关系统调用的国际标准POSIX1003.1(Portable Operating System IX),也称为“基于UNIX的可移植操作系统接口”。
下图示出了UNIX/Linux的系统程序、库函数、系统调用的层次关系。