《UNIX环境高级编程》读书笔记一——UNIX基础知识

一、shell

登陆后,系统先显示一些典型的系统信息,然后可以向shell程序键入命令。shell是一个命令行解释器,它先读取用户的输入,然后执行命令,用户通常用终端,有时通过文件(称为shell脚本)向shell进行输入。常用的shell有:

  • Bourne shell./bin/sh
  • C shell./bin/csh
  • KornShell./bin/ksh

系统从口令文件登陆项的最后一个字段中了解应该执行哪一个shell。

二、文件系统

UNIX文件系统是目录到文件的一种层次安排,目录的起点成为根(root),其名字是一个字符/。

当创建一个新目录时,自动创建了两个文件名:.(称为点)和..(称为点-点)。点引用当前目录,点-点引用父目录。在最高层次的根目录中,点-点和点是相同的。

某些UNIX文件系统限制文件名的最大长度为14个字符,BSD版本则将这种限制扩展为255个字符。

三、路径名

0个或多个以斜线分隔的文件名序列(可以任选地以斜线开头)构成路径名,以斜线开头的路径名称为绝对路径名,否则称为相对路径名

四、文件描述符

文件描述符是一个小的非负整数,内核以标识一个特定进程正在存放的文件。当内核打开一个现存文件或创建一个新文件时,它就返回一个文件描述符。当读、写文件时,就可使用它。

五、标准输入、标准输出或标准出错

按惯例,每当运行一个新程序时,所有的shell都为其打开三个文件描述符:标准输入、标准输出以及标准出错。如果像简单命令ls那样没有做什么特殊处理,则这三个描述符都连向终端。大多数shell都提供一种方法,使任何一个或所有这三个描述符都能重新定向到某一个文件,例如:

执行ls命令,其标准输出重新定向到名为file1.list的文件上。

六、不用缓存的I/O

函数open、read、write、lseek以及close提供了不用缓存的I/O。这些函数都用文件描述符工作。

实例

从标准输入读,并写向标准输出

#include "ourhdr.h"

#define BUFFSIZE 8192

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);
}

两个常熟STDIN_FILENO和SYDOUT_FILENO定义在头文件中,他们指定了标准输入和标准输出的文件描述符。他们的典型值是0和1,但是为了可移植性,我们将使用这些新名字。

read函数返回读得的字节数,此值用作要写的字节数。当到达文件尾端时,read返回0,程序停止执行。如果发生了一个读错误,read返回-1。出错时大多数系统函数返回-1。

如果编译该程序,其结果送入标准的a.out文件,并以下列方式执行它

那么,标准输入是终端,标准输出则重新定向至文件data,标准出错也是终端。如果此输出文件不存在,则shell创建它。

七、出错处理

当UNIX函数出错时,往常返回一个负值,而且整型变量errno通常设置为具有特定信息的一个值。例如,open函数如成功执行则返回一个非负文件描述符,如出错则返回-1。在open出错时,大约有15种不同的errno值(文件不存在,许可权问题等)。某些函数并不返回负值而是使用另一种约定。例如,返回一个指向对象的指针的大多数函数,在出错时,将返回一个null指针。

文件中定义了变量errno以及可以赋予它的各种常数。这些常数都以E开头。例如,errno等于常数EACCES,这表示产生了权限问题(例如,没有打开所要求文件的权限).POSIX定义errno为: extern int errno;

对于errno应当直到两条规则。第一条规则是:如果没有出错,则其值不会被一个例程清除。因此,仅当函数的返回值指明出错时,才检验其值。第二条是:任一函数都不会将errno值设置为0,在中定义的所有常数都不为0

C标准定义了两个函数,它们帮助打印出错信息。

#include 
char* strerror(int errnum);

此函数将errnum(它通常就是errno值)映射为一个出错信息字符,并且返回此字符串的指针。

perror函数在标准出错上产生一条出错信息(基于errno的当前值),然后返回。

#include 
void perror(const char* msg);

它首先输出由msg指向的字符串,然后是一个冒号,一个空格,然后是对应于errno值的出错信息,然后是一个新行符。

两个函数的实例

#include 
#include "ourhdr.h"

int main(int argc,char* argv[])
{
	fprintf(stderr,"EACCES: %s\n",strerror(EACCES));
	errno = ENOENT;
	perror(argv[0]);

	exit(0);
}

如果此程序经编译,结果送入文件a.out,则有:

EACCES: Permission denied
a.out: No such file or directory

argv[0]的值是a.out作为参数传递给perror。

八、UNIX时间值

当度量任一进进程的执行时间,UNIX系统使用三种进程时间值。

  • 时钟时间
  • 用户CPU时间
  • 系统CPU时间

时钟时间又称为墙上时钟时间(wall clock time)。它是进程运行的时间总量,其值与系统中同时运行的进程数有关,在我们报告时钟时间时,都是在系统中没有其它活动时进行的度量。

用户CPU时间是执行用户指令所用的时间量。

系统CPU时间是为该进程执行内核所经历的时间。例如,只要一个进程执行一个系统服务,例如read或write,则在内核内执行该服务所花费的时间就计入该进程的系统CPU时间。

用户CPU时间和系统CPU时间的和常被称为CPU时间。

 

参考书籍:《UNIX系统高级编程》

你可能感兴趣的:(Linux系统编程+网络编程)