除了目录文件之外,Linux系统还有其他的特殊文件,这些文件可以当做普通文件进行处理,但是也有一些特殊性。这里介绍两种特殊文件,一种是符号链接,一种是proc文件系统。
1、符号链接
符号链接是一个重要的概念,符号链接又被称为软连接,在Linux系统中有大量的存在。符号链接可以理解为一个接口,符号链接可以为一个相对封闭的环境提供接口,为一个指向的目的文件提供快捷路径,类似于Windows系统中的快捷方式。
符号链接有两个很重要的特点,第一,符号链接能够方便用户操作。无论你的文件路径有多么复杂,使用符号链接的方式都能够快速的访问到你要访问的文件,不需要经过该文件的路径来访问,方便用户的操作。例如一个文件存放的路径是/home/admin/usr/bin/local/tmp/test.txt,建立一个符号链接s,如果需要对test.txt文件进行读写操作,可以直接对s进行读写操作即可,不用到/home/admin/usr/bin/local/tmp/路径下找到test.txt再进行操作。第二,符号链接增加了系统的安全性。例如,一个银行的系统为例,其内部有a、b、c三个用户,每个客户有一个目录,目录中是客户的信息文件。这三个客户处于一个同一个文件系统中,如下图所示
如果用户a希望自己目录下的password.txt文件对密码进行修改,这时该用户需要经过的路径是/ home/account/Usr_a/dir/password.txt,这时其所经过的目录的安全都会受到威胁。客户a不但可以估算出文件系统的结构,还能得知银行有哪些客户。这些用户操作都为银行系统的安全增加了隐患,同时也存在泄露个人隐私的隐患。如果使用符号链接就能避免这些问题,管理者只需要为password.txt文件新建一个符号链接,客户就可以通过符号链接对password.txt文件进行操作,对于用户来说,整个系统就相当于一个黑匣子。
关于符号链接的操作主要有创建符号链接、读写符号链接的目的文件、读写多重符号链接的目的文件、读写符号链接、取得符号链接的状态、更改符号链接的所有者。因为符号链接自身的特殊性,因此符号链接的操作可以分为两类,一类是针对于符号链接的目的文件的操作,一类是针对于符号链接自身的操作。
创建符号链接使用的函数是 symlink(const char *actualpath, const char *sympath)
头文件: #include <unistd.h>
参数说明:参数1 actualpath表示一个文件的路径,也就是目的文件的路径,这里需要注意的是在创建符号链接的时候,目标文件可以是不存在的,如果目标文件不存在还是会创建这个符号链接;参数2 sympath是新创建的符号链接。
返回值:若成功则返回0,若出错则返回-1。
对于符号链接的操作有两类,对于目标文件的操作和对于符号链接的操作。对于目标文件的读写可以直接用open、read、write函数操作即可;符号链接的本身也是一种文件,其中保存的是目的文件的路径,使用readlink函数进行读操作。
下面两个实际程序代码的对比就能比较出来两者的不同。
对于目的文件读写的代码如下:
1 #include <stdio.h> 2 3 #include <string.h> 4 5 #include <unistd.h> 6 #include <stdlib.h> 7 #include <fcntl.h> 8 #define MAX 1024 9 int main(void) 10 { 11 int fd,n; 12 char buf[MAX]; 13 if(symlink("test.txt", "sym_link") == -1){ /* 创建一个符号链接,目的文件是test.txt */ 14 perror("fail to create symbol link"); 15 exit(1); 16 } 17 printf("already create a symbol-link\n"); /* 输出提示信息 */ 18 if((fd = open("sym_link", O_RDWR)) == -1){ /* 通过符号链接打开该目的文件 */ 19 perror("fail to open"); 20 exit(1); 21 } 22 if((n = read(fd, buf, MAX)) == -1){ /* 读目的文件的内容 */ 23 perror("fail to read"); 24 exit(1); 25 } 26 buf[n] = ‘\0‘; 27 printf("file content is : %s\n", buf); /* 打印目的文件的内容 */ 28 strcat(buf, ", admin"); 29 if(write(fd, buf, strlen(buf)) == -1){ /* 向目的文件输出 */ 30 perror("fail to write"); 31 exit(1); 32 } 33 printf("done\n"); /* 输出提示信息 */ 34 close(fd); 35 return 0; 36 }
读符号链接的程序代码如下:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #define MAX 1024 int main(void) { char buf[MAX]; int fd,n; if(symlink("test.txt", "sl1") == -1){ /* 创建第 一个符号链接,指向test.txt文件 */ perror("fail to create symbol-link"); exit(1); } if(symlink("sl1", "sl2") == -1){ /* 创建第二个符号链接,指向符号链接sl2 */ perror("fail to create symbol-link"); exit(1); } if((n=readlink("sl1", buf, MAX)) == -1){ /* 读取sl1的目的文件test.txt的路径 */ perror("fail to read symbol-link"); exit(1); } buf[n]=‘\0‘; printf("%s\n", buf); /* 输出链接信息 */ if((n=readlink("sl2", buf, MAX)) == -1){ /* 读取sl2的目的文件符号链接sl1的路径 */ perror("fail to read symbol-link"); exit(1); } buf[n]=‘\0‘; printf("%s\n", buf); /* 输出链接信息 */ return 0; }
之前对于文件操作的学习比较扎实的话,主要就是理解一下符号链接的本质,对于符号链接目的文件的操作可以参照普通文件的读写。
硬链接与软连接
之前在学习文件的时候提到了硬链接,今天的符号链接是一种软连接,软硬链接之间有什么区别呢?
硬连接指通过索引节点来进行连接。所以硬链接与源文件共用一个索引节点对象,不共用file对象,不共用dentry对象。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
软连接就是一个文件,通过软连接可以操作目标文件,但是删除软连接与删除目标文件没有必然的关系,删除目标文件软连接可以存在删除软连接,目标文件也可以存在。