UNIX文件和目录笔记

        这篇文章是我自己学习UNIX高级环境编程第四章文件和目录的读书笔记,主要内容是罗列一下本章主要的函数,因为我还是新手,所以有很多知识都理解得不够深刻,如果写得有不对的地方,还希望网友们指证,好了,闲话不多说,开始我们的正题。

文件和目录都是围绕stat函数展开的。首先我们来看看stat函数的原型

    int stat(const char *restrict pathname,struct stat *restrict buf)

一旦给出了pathname,该函数就返回与此命名文件相关的信息,函数会填写一个buf指向的结构,那这个结构有些什么信息呢?我们来看一下这个结构的原型

      struct stat  {

          mode_t     st_mode; //文件类型

        info_t       st_ino;    //i节点编号

dev_ts t_dev; //设备号

nlink_t st_nlink; //文件链接数

uid_t  st_uid; //文件所以者的用户ID

gid_t st_gid; //文件所有者所在的组ID

off_t st_size; //文件大小,单位为bytes

time_t st_atime; //文件最后访问时间

time_t st_mtime; //文件最后修改时间

time_t st_ctime; //文件状态修改的最后时间

blksize_t st_blksize; //最合适的I/O块大小

blkcnt_t  st_block; //磁盘所分配的块的数量

}

我当时都看得头晕眼花了,反正大家理解就是这是一个结构体,里面有很多关于文件的信息,然后对于这个结构体里面的信息,UNIX提供了很多函数以供对这个结构体的成员变量进行修改,下面我们展开看一下这些修改成员变量的函数吧。

一、文件类型

1、文件分类,这个不用多说,罗列一下就行,UNIX提供了以下七种文件,普通文件,目录文件,字符特殊文件,块特殊文件,管道或者FIFO,符号链接,套接字文件。

2、文件权限,这是这章的重中之重,可以说掌握了文件权限,你对文件系统的认识会加深很多,那和我一起来理清一下这里面的具体细节吧。

  首先我们得把一大堆该死的概念弄清楚,直接从鸟哥书上搞了个图,上图比啥都清楚

大家看到了吧,所谓权限就是这么回事,“王大毛家”和“张小猪家”就是组ID,王大毛,王二毛,王三毛就是用户ID,至于那个万能的天神,就是root,我们可以忽略它。

就这个图而言我们要理解以下几点:

1.王大毛和王二毛虽然同属一个组,但是他们还是可以设置自己的权限,意思是说,他们都有各自的房间,如果王大毛去找二毛,得先敲敲门,不然是没法进的;当然他们共享客厅,只要是王大毛家这个组。举个例子加深一下理解:

王大毛设置权限如下:- |r w x| r - x| - - -。意思是自己对自己所有的东西都有使用权,读写执行,组里面的其它成员有读和执行权限,也就是所其它两个人可以进他的房间,可以玩儿他的电脑啥的,但是不能在他的房间墙上乱画啥的。对于张小猪,他不能进王大毛家,反正就是和大毛事没得交集的。

2.一些枯燥的理论知识:

实际用户ID和实际组ID:标识的是我们究竟是谁,这两个字段在登录时有用,在会话期间保持不变;

有效用户ID和有效组ID:决定了我们的文件访问权限。这两个ID是可以设置的。通常设置为实际ID号。

最直观的例子就是用户改密码,我们知道,UNIX密码文件在/etc/shadow文件中,普通用户时不能写入的,那我们怎么修改自己的口令呢?原理如下,当用户运行时,将有效ID设置为root之类,这个时候该用户就有了超级管理员权限,就可以修改密码啦。。。。

设置用户ID和设置组ID:这玩意儿就是有效用户ID和有效组ID的副本。

3.目录的执行权限,这个一度困扰我很久,我以前天真的认为,只要对目录有读权限,那我们就可以在目录里面为所欲为了啥,UNIX可不这么干,还给我增加了个执行权限,其实说白了就是:当有目录读权限时,你是可以看目录下有什么文件或者子目录,但是你想进去目录继续访问,那你必须得先得有执行权限才行。平常生活中是不是有很多例子嘛,看马戏,会给你露一个小缝,给你看看都有些啥子,要进去舒舒服服的看,那对不起,先买票,这个票就是执行权限的意思哦。

4.新文件和目录的所有权:新文件的用户ID就是当前用户的有效ID,组ID就是它所在的目录的组ID,意思就是说,这个组ID兴许不是当前进程的组ID。比如王大毛成家了,家里出生了个小孩,当然这个小孩子的用户ID肯定就是他父亲了啥,跟着他父亲姓嘛,但是他小孩儿不一定会在他这家长大啥,因为王大毛买了个新房子,这个小孩的组ID就是那个新家了啥。。大概是这个意思,我都有点糊涂了,呵呵。

通过以上几点的阐述,再去看书上的这种ID那种ID就轻松得多了哦。。。。。。

二、文件系统:

同样采取同样的方法,来细分一下,理解几个关键的概念。

1、目录:目录是干啥的,比如书的目录,或者说windows系统的目录,目录是一种文件,通俗点说其实就是一个路径啦,目录可以有子目录,在UNIX里边,子目录称呼为目录项,目录下面可以有文件,这点倒是很容易理解的。

2、目录项:目录项的内容也不复杂,一个目录项主要包括了文件名和索引节点(i节点)号,索引节点号是指向索引节点表( system inode table )中对应的索引节点的

3.i节点:i节点就是实际指向一个文件的东东,主要就是文件的属性,包括链接数、文件所有者、文件建立和修改的时间,文件在磁盘的位置,文件大小、使用权限等等。

总结一下,就是说,目录文件包含目录项,目录项又可以包含文件。

4.硬链接和符号链接:这个我就从网上copy的一个博文了哈,感谢那个伟大的博主,让我理解得很是深刻:

【硬连接】
硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

【软连接】
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

2.通过实验加深理解
[oracle@Linux]$ touch f1          #创建一个测试文件f1
[oracle@Linux]$ ln f1 f2          #创建f1的一个硬连接文件f2
[oracle@Linux]$ ln -s f1 f3       #创建f1的一个符号连接文件f3
[oracle@Linux]$ ls -li            # -i参数显示文件的inode节点信息
total 0
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f1
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f2
9797649 lrwxrwxrwx  1 oracle oinstall 2 Apr 21 08:11 f3 -> f1

从上面的结果中可以看出,硬连接文件f2与原文件f1的inode节点相同,均为9797648,然而符号连接文件的inode节点不同。

[oracle@Linux]$ echo "I am f1 file" >>f1
[oracle@Linux]$ cat f1
I am f1 file
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
I am f1 file
[oracle@Linux]$ rm -f f1
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
cat: f3: No such file or directory

通过上面的测试可以看出:当删除原始文件f1后,硬连接f2不受影响,但是符号连接f1文件无效

3.总结
依此您可以做一些相关的测试,可以得到以下全部结论:
1).删除符号连接f3,对f1,f2无影响;
2).删除硬连接f2,对f1,f3也无影响;
3).删除原文件f1,对硬连接f2没有影响,导致符号连接f3失效;
4).同时删除原文件f1,硬连接f2,整个文件会真正的被删除。

三、文件时间以及其它零碎知识点

文件时间分为:文件数据最后访问时间,文件数据最后修改时间,i节点状态的最后更改时间。

修改时间和更改状态时间之间的区别:修改时间是文件内容最后一次修改时间,更改状态时间是该文件i节点最后一次修改的时间,i节点修改比如权限,用户ID,链接数等,他们并没有改变文件的实际内容

至于后面的设备啥的,就比较鸡肋了,也没仔细看过,所以就不做阐述了。

文章最后我来罗列一下对于文件和目录操作的函数,以便大家查阅:

access函数:按照实际用户ID和实际组ID进行访问权限的测试;

设置文件权限:

umask函数:mode_t umask(mode_t cmask);创建文件的屏蔽字,也就是文件的访问权限;

更改文件权限:

int chmod(const char* pathname,mode_t mode);在指定的文件上操作

int fchmod(int filedes,mode_t mode);在已经打开的文件上操作

int chown(const char* pathname,uid_t owner,gid_t group);

int fchown(int fileds,uid_t owner,gid_t group);

int lchown(const char* pathname,uid_t owner,gid_t group);

文件链接:

硬链接:

int link(const char* existingpath,const char *newpath);创建一个目录项newpath,引用现有文件existingpath。如果newpath存在,则出错。如果说是创建目录的硬链接,只有超级用户有资格

int unlink(const char* pathname);删除一个现有的目录项。如果删除之后,其文件链接数不为0,那么仍然可以通过其他链接访问该目录

符号链接:

int symlink(const char* actualpath,const char* sympath);//不要求sympath存在,也不要求两个变量在同一个文件系统中

ssize_t readlink(const char* restrict pathname,char* restrict buf,size_t bufsize);//打开符号链接,读取该链接中的名字

更改文件时间:

int utime(const char* pathname,const struct utmibuf* times);//times为空指针,则将时间修改为当前时间,不为空,则设置为time指向的时间

目录操作

int mkdir(const char* pathname,mode_t mode);//创建空目录,中.和..目录项是自动创建的。

int rmdir(const char* pathname);//删除一个空目录。

int chdir(const char* pathname);//更改当前工作目录

int fchdir(int fildes);

好了,以上就是我看书的一些笔记,当然这其中省略了很多细节,但是我觉得从宏观把握更为重要,因为细节总是那么多那么详细,凭记忆力是无法记住这么多东西,我更赞同的是,理解UNIX对于文件的管理的大方向,然后把UNIX环境编程作为一本工具书,不会的去看看查查,了解其中的一些细节,这样或许学习效率要高很多。如果有写的不对的地方,希望网友们指证批评,谢谢。








 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章