1.UNIX体系结构:
严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核,因为它相对较小,而且位于环境的核心。图1-1显示了UNIX系统的体系结构。
内核的接口被称为系统调用(system call)。公用函数库构建在系统调用接口之上,应用程序既可以使用公用函数库,也可以使用系统调用。shell时一个特殊的应用程序,为运行其他应用程序提供了一个接口。
从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特性。这里所说的其他软件包括系统使用程序(system utility),应用程序,shell以及公用函数库等。
例如,Linux时GNU操作系统使用的内核。一些人将这种操作系统称为GNU/Linux操作系统,但是,更常见的是简单称其为Linux。虽然这种表达方式在严格意义上并不正确,但鉴于“操作系统”这个词的双重含义,这种叫法还是可以理解的。
2.登录
(1)登录名:
用户在登录UNIX系统时,先键入登录名,然后键入口令。系统在其口令文件(通常是/etc/passwd文件)中查看登录名。口令文件中的登陆项由7个以冒号分隔的字段组成,依次是:登录名,加密口令,数字用户ID(205),数字组ID(105),注释字段,起始目录(/home/sar)以及shell程序(/bin/ksh)。
例:sar: x:205:105:Stephen Rago:/home/sar:/bin/ksh
目前,所有的系统已将加密口令移到另一个文件中。第6章将说明这种文件以及访问它们的函数。
(2)shell:
用户登陆后,系统通常先显示一些系统信息,然后用户向shell程序键入命令。(当用户登录时,某些系统启动一个视窗管理程序,但最终总会有一个shell程序运行在一个视窗中)。shell是一个命令行解释器,它读取用户输入,然后执行命令。shell的用户输入通常来自于终端,有时则来自于文件(称为shell脚本),图1-2总结了UNIX系统中常见的shell。
系统从口令文件中相应的用户登陆项最后一个字段中了解到应该为该登录用户执行哪一个shell。
自V7以来,由由Steve Bourne在贝尔实验室开发的Bourne shell得到了广泛应用,几乎每一个现有的UNIX系统都提供Bourne shell,其控制流结构类似于Algol 68。
C shell是由Bill Joy在伯克利开发的,所有BSD版本都提供这种shell。另外,AT&T的System V/386 R3.2和System V R4(SVR4)也提供了C shell(下一章将对这些不同版本的UNIX系统做更多说明)。
C shell是在第6版shell而非Bourne shell的基础上构造的,其控制流类似于C语言,它支持Bourne shell没有的一些特色功能,例如作业控制,历史机制以及命令行编辑等。
Korn shell是在Bourne shell的后继者,它首先在SVR4中提供。
Korn shell是由贝尔实验室的David Korn开发的,在大多数UNIX系统系统上运行,但在SVR4之前,通常它需要另行购买,所以没有其他两种shell流行。它与Bourne shell向上兼容,并具有使C shell广泛得到应用的一些特色功能,包括作业控制以及命令行编辑等。
Bourne-again shell是GNU shell,所有Linux系统都提供这种shell。它的设计遵循POSIX标准,同时也保留了与Bourne shell的兼容性。它支持C shell和Korn shell两者的特殊功能。
TENEX C shell是C shell的加强版本。它从TENEX操作系统借鉴了很多特殊,例如命令完备。
POSIX 1003.2标准对shell进行了标准化。这项规范基于Korn shell和Bourne shell的特性。
3.文件和目录:
(1)文件系统
Unix文件系统是目录和文件的一种层次结构,所有东西的起点是称为根(root)的目录,这个目录的名称是一个字符"/"。
目录是一个包含目录项的文件。在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。文件属性是指文件类型,文件大小,文件所有者,文件权限以及文件最后的修改时间等。stat和fstat函数返回包含所有文件属性的一个信息结构。第4章将详细说明文件的各种属性。
目录项的逻辑试图与实际存放在磁盘上的方式是不同的。UNIX文件系统的大多数实现并不在目录项中存放属性,这是因为当一个文件具有多个硬链接时,很难保持多个属性副本之间的同步。这一点将在第4章讨论硬链接时理解得更明晰。
(2)文件名
目录中的各个名字称为文件名。只有斜线/和空字符这两个字符不能出现在文件名中。斜线用来分隔构成路径的各个文件名,空字符则用来终止一个路径名。尽管如此,好的习惯还是只使用常用印刷字符的一个子集作为名字符。
创建新目录时会自动创建了两个文件名:.(称为点),.(称为点点)。点指向当前目录,点点指向父目录。在最高层次的根目录中,点点与点相同。
(3)路径名
由斜线分割的一个或多个文件名组成的序列构成路径名,以斜线开头的路径名称称为绝对路径名,否则称为相对路径名。相对路径名指向相对于当前目录的文件。文件系统根的名字(/)是一个特殊的绝对路径名,它不包含文件名。
(4)工作目录
每个进程都有一个工作目录,有时诚其为当前工作目录。所有相对路径名都从工作目录开始解释。进程可以用chdir函数更改其工作目录。
例如,相对路径名doc/memo/joe指的是当前工作目录中的doc目录中的memo目录中的文件joe。从该路径名可以看出,doc和memo都应当是目录,但是不能分辨joe是文件还是目录。
4.输入输出
(1)文件描述符
文件描述符通常是一个小的非负整数,内核用以标识一个特定进程正在访问的文件。当内核打开一个现有文件或创建一个新文件时,它都返回一个文件描述符。在读,写文件时,可以使用这个文件秒数符。
(2)标准输入,标准输出和标准错误
按惯例,每当运行一个新程序时,所有的shell都为其打开3个文件描述符,即标准输入,标准输出以及标准错误。如果不做特殊处理,例如就像简单的命令ls,则这3个描述符都链接向终端。大多数shell都提供一种方法,使其中任何一个或所有这3个描述符都能重新定向到某个文件,例如:
ls > file.list
执行ls命令,其标准输出重新定向到名为file.list的文件。
(3)不带缓冲的IO
函数open,read,write,lseek以及close提供了不带缓冲的IO。这些函数都是用文件描述符。
实例:程序1-4
#include "apue.h"
#define BUFFSIZE 4096
int main(void)
{
int n;
char buf[BUFFSIZE];
while((n==read(STDIN_FILENO,buf,BUFFSIZE))>0)
if (write(STDOUT_FILENO,buf,n)!=n)
err_sys("write error");
if (n<0)
err_sys("read error");
exit(0);
}
①头文件<unistd.h>(包含与apue.h)及两个常量STDIN_FILENO和STDOUT_FILENO是POSIX标准的一部分