UNIX环境高级编程.pdf
《UNIX环境高级编程.pdf》由会员分享,可在线阅读,更多相关《UNIX环境高级编程.pdf(552页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第1章U N I X基础知识1.1 引言所有操作系统都向它们运行的程序提供服务。典型的服务有执行新程序、打开文件、读文件、分配存储区、获得当前时间等等,本书集中阐述了 U N I X操作系统各种版本所提供的服务。以严格的步进方式、不超前引用尚未说明过的术语的方式来说明 U N I X几乎是不可能的(可能也会是令人厌烦的)。本章从程序设计人员的角度快速浏览 U N I X,并对书中引用的一些术语和概念进行简要的说明并给出实例。在以后各章中,将对这些概念作更详细的说明。本章也对不熟悉U N I X的程序设计人员简要介绍了U N I X提供的各种服务。1.2 登录1.2.1 登录名登录 U N I
2、X系统时,先键入登录名,然后键入口令。系统在其口令文件,通常是/e t c/p a s s w d文件中查看登录名。口令文件中的登录项由 7个以冒号分隔的字段组成:登录名,加密口令,数字用户I D(2 2 4),数字组I D(2 0),注释字段,起始目录(/h o m e/s t e v e n s),以及s h e l l程序(/b i n/k s h)。很多比较新的系统已将加密口令移到另一个文件中。第 6章将说明这种文件以及存取它们的函数。1.2.2 shell登录后,系统先显示一些典型的系统信息,然后就可以向 s h e l l程序键入命令。s h e l l是一个命令行解释器,它读取用
3、户输入,然后执行命令,用户通常用终端,有时则通过文件(称为s h e l l脚本)向s h e l l进行输入。常用的s h e l l有:Bourne shell,/bin/sh C shell,/bin/csh KornShell,/bin/ksh系统从口令文件中登录项的最后一个字段中了解到应该执行哪一个 s h e l l。自V 7以来,Bourne shell得到了广泛应用,几乎每一个现有的U N I X系统都提供Bourne shell。C shell是在伯克利开发的,所有B S D版本都提供这种s h e l l。另外,AT&T的系统V/386 R3.2和S V R 4也提供C s
4、hell(下一章将对这些不同的U N I X版本作更多说明)。K o r n S h e l l是Bourne shell的后继者,它由S V R 4提供。K o r n S h e l l在大多数U N I X系统上运行,但在S V R 4之前,通常它需要另行购买,所以没有其他两种s h e l l流行。本书将使用很多s h e l l实例,以执行已开发的程序,其中将应用 Bourne shell和K o r n S h e l l都具有的功能。更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o k 本站提供的电子书教程均为网上搜
5、集,如果该教程涉及或侵害到您的版权请联系我们。Bourne shell是Steve Bourne在贝尔实验室中开发的,其控制流结构使人想起Algol 68。C shell是在伯克利由Bill Joy完成的,其基础是第6版s h e l l(不是B o u r n es h e l l)。其控制结构很像C语言,它支持一些Bourne shell没有提供的功能,如作业控制,历史机制和命令行编辑。K o r n S h e l l是David Korn在贝尔实验室中开发的,它兼容Bourne shell,并且也包含了使C shell非常流行的一些功能,如作业控制、命令行编译等。本书将使用这种形式的注
6、释来描述历史,并对不同的 U N I X实现进行比较。当我们了解了历史缘由后,采用某种特定实现技术的原因将变得清晰起来。1.3 文件和目录1.3.1 文件系统U N I X文件系统是目录和文件的一种层次安排,目录的起点称为根(r o o t),其名字是一个字符/。目录(d i r e c t o r y)是一个包含目录项的文件,在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。文件属性是:文件类型,文件长度,文件所有者,文件的许可权(例如,其他用户能否能访问该文件),文件最后的修改时间等。s t a t和f s t a t函数返回一个包含所有文件属性的信息结构。第4
7、章将详细说明文件的各种属性。1.3.2 文件名目录中的各个名字称为文件名(f i l e n a m e)。不能出现在文件名中的字符只有两个,斜线(/)和空操作符(n u l l)。斜线分隔构成路径名(在下面说明)的各文件名,空操作符则终止一个路径名。尽管如此,好的习惯是只使用印刷字符的一个子集作为文件名字符(只使用子集的理由是:如果在文件名中使用了某些s h e l l特殊字符,则必须使用s h e l l的引号机制来引用文件名)。当创建一个新目录时,自动创建了两个文件名:.(称为点)和.(称为点-点)。点引用当前目录,点-点则引用父目录。在最高层次的根目录中,点-点与点相同。某些U N I
8、 X文件系统限制文件名的最大长度为1 4个字符,B S D版本则将这种限制扩展为2 5 5个字符。1.3.3 路径名0个或多个以斜线分隔的文件名序列(可以任选地以斜线开头)构成路径名(p a t h n a m e),以斜线开头的路径名称为绝对路径名(absolute pathname),否则称为相对路径名(r e l a t i v ep a t h n a m e)。实例不难列出一个目录中所有文件的名字,程序1-1是l s(1)命令的主要实现部分程序1-1 列出一个目录中的所有文件 更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o
9、 o k 本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。l s(1)这种表示方法是U N I X的惯用方法,用以引用U N I X手册集中的一个特定项。它引用第一部分中的l s项,各部分通常用数字1至8表示,在每个部分中的各项则按字母顺序排列。假定你有一份所使用的U N I X系统的手册。早期的U N I X系统把8个部分都集中在一本手册中,现在的趋势是把这些部分分别安排在不同的手册中:有用户专用手册,程序员专用手册,系统管理员专用的手册等等。某些U N I X系统把一个给定部分中的手册页又用一个大写字母进一步分成若干小部分,例如,AT&T1 9 9 0 e中的所
10、有标准I/O函数都被指明在3 S部分中,例如f o p e n(3 S)。某些U N I X系统,例如以X e n i x为基础的系统,不是采用数字将手册分成若干部分,而是用C表示命令(第1部分),S表示服务(通常是第2、3部分)等等。如果你有联机手册,则可用下面的命令查看l s命令手册页:man 1 ls程序1-1只打印一个目录中各个文件的名字,不显示其他信息,如若该源文件名为 m y l s.c,则可以用下面的命令对其进行编译,编译的结果送入系统默认名为 a.o u t的可执行文件名:cc myls.c某种样本输出是:$a.out/dev.M A K E D E Vc o n s o l
11、et t ym e mk m e mn u l l此处略去多行 更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o k 本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。p r i n t e r$a.out/var/spool/mqueuecant open/var/spool/mqueue:Permission denied$a.out/dev/ttycant open/dev/tty:Not a directory本书将以这种方式表示输入的命令以及其输出:输入的字符以粗体表示,程序输出则以另一种字体表
12、示。如果欲对输出添加注释,则以中文宋体表示,输入之前的美元符号($)是s h e l l打印的提示符,本书将s h e l l提示符显示为$。注意,列出的目录项不是以字母顺序排列的,l s命令则一般按字母顺序列出目录项。在这2 0行的程序中,有很多细节需要考虑:首先,其中包含了一个头文件o u r h d r.h。本书中几乎每一个程序都包含此头文件。它包含了某些标准系统头文件,定义了许多常数及函数原型,这些都将用于本书的各个实例中,附录B列出了常用头文件。main函数的说明使用了ANSI C标准所支持的新风格(下一章将对ANSI C作更多说明)。取命令行的第1个参数a rg v1作为列出的目录
13、名。第7章将说明m a i n函数如何被调用,程序如何存取命令行参数和环境变量。因为各种不同U N I X系统的目录项的实际格式是不一样的,所以使用函数 o p e n d i r,readdir和c l o s e d i r处理目录。opendir函数返回指向D I R结构的指针,并将该指针传向 r e a d d i r函数。我们并不关心 D I R结构中包含了什么。然后,在循环中调用 r e a d d i r来读每个目录项。它返回一个指向 d i r e n t结构的指针,而当目录中已无目录项可读时则返回 n u l l指针。在d i r e n t结构中取出的只是每个目录项的名字(
14、d _ n a m e)。使用该名字,此后就可调用 s t a t函数(见4.2节)以决定该文件的所有属性。调用了两个自编的函数来对错误进行处理:e r r _ s y s和e r r _ q u i t。从上面的输出中可以看到,e r r _ s y s函数打印一条消息(“Permission denied(许可权拒绝)”或“Not a directory(不是一个目录)”),说明遇到了什么类型的错误。这两个出错处理函数在附录 B中说明,1.7节将更多地叙述出错处理。这两个出错处理函数在附录 B中说明1.7节将更详细地叙述出错处理。当程序将结束时,它以参数0调用函数e x i t。函数e x
15、 i t终止程序。按惯例,参数0的意思是正常结束,参数值12 5 5则表示出错。8.5节将说明一个程序(例如s h e l l或我们所编写的程序)如何获得它所执行的另一个程序的e x i t状态。1.3.4 工作目录每个进程都有一个工作目录(working directory,有时称为当前工作目录(current workingd i r e c t o r y)。所有相对路径名都从工作目录开始解释。进程可以用c h d i r函数更改其工作目录。例如,相对路径名d o c/m e m o/j o e指的是文件j o e,它在目录m e m o中,而m e m o又在目录d o c中,d o
16、c则应是工作目录中的一个目录项。从该路径名可以看出,d o c和m e m o都应当是目录,但是却不清楚j o e是文件还是目录。路径名/u r s/l i b/l i n t是一个绝对路径名,它指的是文件(或目录)lint,而l i n t在目录l i b中,l i b则在目录u s r中,u s r则在根目录中。1.3.5 起始目录登录时,工作目录设置为起始目录(home directory),该起始目录从口令文件(见1.2节)中 更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o k 本站提供的电子书教程均为网上搜集,如果该教
17、程涉及或侵害到您的版权请联系我们。的登录项中取得。1.4 输入和输出1.4.1 文件描述符文字描述符是一个小的非负整数,内核用以标识一个特定进程正在存访的文件。当内核打开一个现存文件或创建一个新文件时,它就返回一个文件描述符。当读、写文件时,就可使用它。1.4.2 标准输入、标准输出和标准出错按惯例,每当运行一个新程序时,所有的 s h e l l都为其打开三个文件描述符:标准输入、标准输出以及标准出错。如果像简单命令 l s那样没有做什么特殊处理,则这三个描述符都连向终端。大多数s h e l l都提供一种方法,使任何一个或所有这三个描述符都能重新定向到某一个文件,例如:ls file.li
18、st执行l s命令,其标准输出重新定向到名为f i l e.l i s t的文件上。1.4.3 不用缓存的I/O函数o p e n、r e a d、w r i t e、l s e e k以及c l o s e提供了不用缓存的I/O。这些函数都用文件描述符进行工作。实例如果愿意从标准输入读,并写向标准输出,则程序1-2可用于复制任一U N I X文件。程序1-2 将标准输入复制到标准输出头文件(o u r h d r.h中包含了此头文件)及两个常数S T D I N _ F I L E N O和S T D O U T _F I L E N O是P O S I X标准的一部分(下一章将对此作更多的
19、说明)。很多U N I X系统服务的函数原型,例如我们调用的r e a d和w r i t e都在此头文件中。函数原型也是ANSI C标准的一部分,本章的 更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o k 本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。稍后部分将对此作更多说明。两个常数S T D I N _ F I L E N O和S T D O U T _ F I L E N O定义在头文件中,它们指定了标准输入和标准输出的文件描述符。它们的典型值是 0和1,但是为了可移植性,我们将使用这些新名
20、字。3.9节将详细讨论B U F F S I Z E常数,说明各种不同的值将如何影响程序的效率。但是不管该常数的值如何,此程序总能复制任一U N I X文件。r e a d函数返回读得的字节数,此值用作要写的字节数。当到达文件的尾端时,r e a d返回0,程序停止执行。如果发生了一个读错误,r e a d返回1。出错时大多数系统函数返回1。如果编译该程序,其结果送入标准的a.o u t文件,并以下列方式执行它:a.out data那么,标准输入是终端,标准输出则重新定向至文件 d a t a,标准出错也是终端。如果此输出文件并不存在,则s h e l l创建它。第3章将更详细地说明不用缓存的
21、I/O函数。1.4.4 标准I/O标准I/O函数提供一种对不用缓存的I/O函数的带缓存的界面。使用标准I/O可无需担心如何选取最佳的缓存长度,例如程序 1-2中的B U F F S I Z E常数。另一个使用标准 I/O函数的优点与处理输入行有关(常常发生在U N I X的应用中)。例如,f g e t s函数读一完整的行,而另一方面,r e a d函数读指定字节数。我们最熟悉的标准I/O函数是p r i n t f。在调用p r i n t f的程序中,总是包括(通常包括在o u r h d r.h中),因为此头文件包括了所有标准I/O函数的原型。实例程序1-3的功能类似于调用r e a d
22、和w r i t e的前一个程序1-2,5.8节将对程序1-3作更详细的说明。它将标准输入复制到标准输出,于是也就能复制任一U N I X文件。程序1-3 用标准I/O将标准输入复制到标准输出函数g e t c一次读1个字符,然后p u t c将此字符写到标准输出。读到输入的最后 1个字节时,g e t c返回常数E O F。标准输入、输出常数s t d i n和s t d o u t定义在头文件中,它们分别表示标准输入和标准输出文件。更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o k 本站提供的电子书教程均为网上搜集,如果该教
23、程涉及或侵害到您的版权请联系我们。1.5 程序和进程1.5.1 程序程序(p r o g r a m)是存放在磁盘文件中的可执行文件。使用 6个e x e c函数中的一个由内核将程序读入存储器,并使其执行。8.9节将说明这些e x e c函数。1.5.2 进程和进程I D程序的执行实例被称为进程(p r o c e s s)。本书的每一页几乎都会使用这一术语。某些操作系统用任务表示正被执行的程序。每个U N I X进程都一定有一个唯一的数字标识符,称为进程 I D(process ID)。进程I D总是一非负整数。实例程序1-4用于打印进程I D。程序1-4 打印进程I D如果要编译该程序,其
24、结果送入a.o u t文件,然后执行它,则有:$a.o u thello world from process ID 851$a.o u thello world from precess ID 854此程序运行时,它调用函数g e t p i d得到其进程I D。1.5.3 进程控制有三个用于进程控制的主要函数:f o r k、e x e c和w a i t p i d(e x e c函数有六种变体,但经常把它们统称为e x e c函数)。实例程序1-5 从标准输入读命令并执行 更多电子书教程下载请登陆h t t p:/d o w n.z z b a i k e.c o m/e b o o
25、k 本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。U N I X的进程控制功能可以用一个较简单的程序(见程序 1-5)说明,该程序从标准输入读命令,然后执行这些命令。这是一个类似于 s h e l l程序的基本实施部分。在这个 3 0行的程序中,有很多功能需要思考:用标准I/O函数f g e t s从标准输入一次读一行,当键入文件结束字符(通常是 C t r l-D)作为行的第1个字符时,f g e t s返回一个n u l l指针,于是循环终止,进程也就终止。第11章将说明所有特殊的终端字符(文件结束、退格字符、整行擦除等等),以及如何改变它们。因为f g e
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UNIX 环境 高级 编程
限制150内