unix高级环境编程学习(一) ---------------基础知识

时间:2021-08-04 03:30:16

内核的接口被称为系统调用

公用函数库构建再系统调用接口之上

应用程序可以调用公共函数库,也可以使用系统调用。

shell是一种特殊的应用程序,为运行其他应用程序提供了一个接口。

shell:

shell是一个命令行解释器,读取用户输入然后执行命令,

用户输入可以来自于终端(交互式shell),也可以来自于文件(shell脚本)

常见的shell有五种(Bourne shell,Bour-again shell,C shell,Korn shell,TENEX C shell)

系统从口令文件中相应的用户登录项的最后一个字段中了解到应该为登录用户执行哪一个shell

五种shell的特点就不一一赘述了,不同的系统实用的shell不尽相同,根据实际所使用的系统自己发现

文件和目录:

文件系统-unix的文件系统是目录和文件的一种层次结构,所有的东西的起点称为根目录”/“

目录是一个包含目录项的文件,逻辑上可以认为每个目录项都包含一个文件,同时包含说明文件属性的信息。

文件属性是指文件类型(是目录还是普通文件等),文件大小,文件所有者,文件权限,文件最后修改时间。;两个函数:stat和fstat函数返回包含所有文件属性的一个信息结构。(目录项的逻辑视图与实际存放再磁盘上的方式是不同的,并不是一定再目录中存放属性,因为当一个文件具有多个硬连接,因为各个属性副本很难保持同步)

文件名中不能出现”/“和空字符,”/“用来分隔构成路径名的各文件名,空字符用来终止一个路径名,尽量不要使用shell的某些特殊字符,尽量使用(a~z,A~Z,0~9, 。 , -,_)

创建新目录会自动生成 . 和 ..两个文件。 .指向当前目录 ..指向父目录。

大部分的unix文件系统都支持超过255个字符的文件名

路径名:

/开头的为绝对路径名,其他的则为相对路径名

ls命令的实现--例

#include "apue.h" //需要解压src.3e.tar.gz,复制其下的apue.h和error.c 到当前目录
#include <dirent.h>

int main(int argc,char *argv[])
{
    DIR  *dp;
    struct dirent *dirp;
    if(argc != 2)
    {
        err_quit("usage: ls directory_name");
    }

    if((dp = opendir(argv[1])) == NULL)
    {
        err_sys("can't open %s\n",argv[1]);
    }

    while((dirp = readdir(dp)) != NULL)
    {
        printf("%s\n",dirp->d_name);
    }
    closedir(dp);
    exit(0);//调用exit(0),正常退出,通常1~255表示出错
}


exit(0)和return 0;的区别:

return是一个关键字,exit()是一个函数

return 返回的是函数值,属于调用堆栈的返回,是函数的退出,return是C语言提供

exit()是系统调用级别,直接结束整个程序(结束进程),是进程的退出,exit()是操作系统或函数库提供。

更详细内容参照

http://blog.csdn.net/jody1989/article/details/6821477


./a.out  目录


工作目录:

每一个进程都有一个工作目录(或称其为当前工作目录),所有绝对路径名都从工作目录开始解释。进程可以用成chdir来更改其工作目录。

即/user/lib 是根目录下的user文件下的lib文件/目录  而user/lib是指当前目录下的user目录下的lib文件/目录

输入输出:

文件描述符:

一个非负整数,内核用来表示一个特定的进程正在访问的文件,当内核打开一个现有文件或创建一个新文件时,它都会返回一个文件描述符,在读,写文件时,都可以使用文件描述符

标准输入,标准输出和标准错误

每当运行一个程序时,shell都会为它打开3个文件描述符,即标准输入(standard input),标准输出(standard output)以及标准错误(standard error)。默认情况下这三个描述符都链接向终端,大部分shell提供分别将这三个描述符重定向,例如;ls>*.list,就是将标准输出重定向到*.list文件中

不带缓冲的I/O

函数open,read,write,lseek,close提供不带缓冲的I/O。这些函数都使用文件描述符

例如:

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


cc  -*.c 

./a.out  文件1   文件2  //将文件1的内容拷贝进文件2,

另外此程序效率受BUFFSIZE影响,无法自动选取最优缓存大小,

另外 当输出时也是输入的文件描述符,./a.out会将在终端写入的信息再次打印在终端


程序和进程

程序是放在磁盘上的可执行程序,内核使用exec(7个exec函数之一)将程序读入内存,并执行

进程和进程ID:

程序的执行过程叫做进程,某些操作系统使用任务来表示进程

每个进程都有唯一的进程ID(非负整数)

例如:

#include "apue.h"
int main()
{
    printf("process ID:%ld\n",(long)getpid());
    exit(0);
}

./a.out 会打印出这个程序执行时的进程ID每次不尽相同,之所以强转为long是因为我们不知道它的大小,但我们知道其最大为long,同时也是为了提高可移植性

进程控制

fork创建一个进程,

。。。。未完待续