一、目录和(硬)链接
-
可在 shell 中利用 ln 命令为一个业已存在的文件创建新的硬链接
添加图片注释,不超过 140 字(可选)
2. 同一文件的所有名字(链接)地位平等—没有一个名字(比如,第一个)会优于其他名字。
3. 对硬链接的限制有二,均可用符号链接来加以规避。
-
因为目录条目(硬链接)对文件的指代采用了 i-node 编号,而 i-node 编号的唯一性仅 在一个文件系统之内才能得到保障,所以硬链接必须与其指代的文件驻留在同一文 件系统中。
-
不能为目录创建硬链接,从而避免出现令诸多系统程序陷于混乱的链接环路。
二、符号(软)链接
-
符号链接,有时也称为软链接,是一种特殊的文件类型,其数据是另一文件的名称。
2. 在 shell 中,符号链接是由 ln–s 命令创建的。ls–F 命令的输出结果中会在符号链接的尾部标记@。
3. 符号链接的地位不如硬链接。尤其是,文件的链接计数中并未将符号链接计算在内。因此,如果移除了符号链接所指向的文件名,符号链接本身还将继续存在,尽管无法再对其进行解引用(下溯)操作,也将此类链 接称之为悬空链接。更有甚者,还可以为并不存在的文件名创建一个符号链接。
三、系统调用对符号链接的解释
-
许多系统调用都会对符号链接进行解引用处理(即下溯 follow),从而对链接所指向的 文件展开操作。还有一些系统调用对符号链接则不作处理,直接操作于链接文件本身。
2. 符号链接的文件权限和所有权
-
大部分操作会无视符号链接的所有权和权限(创建符号链接时会为其赋予所有权限)。 是否允许操作反而是由符号链接所指代文件的所有权和权限来决定。仅当在带有粘性权限 位(15.4.5 节)的目录中对符号链接进行移除或改名操作时,才会考虑符号链接自身的所 有权。
四、创建和移除(硬)链接:link()和 unlink()
-
link() 系统调用创建硬链接
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
-
若 oldpath 中提供的是一个已存在文件的路径名,则系统调用 link()将以 newpath 参数所指 定的路径名创建一个新链接。若 newpath 指定的路径名已然存在,则不会将其覆盖;相反,将 产生一个错误(EEXIST)。
-
在 Linux 中,link()系统调用不会对符号链接进行解引用操作。若 oldpath 属于符号链接, 则会将 newpath 创建为指向相同符号链接文件的全新硬链接。(换言之,newpath 也是符号链 接,指向 oldpath 所指代的同一文件。)
2. unlink()系统调用移除硬链接
#include <unistd.h>
int unlink(const char *pathname);
-
unlink()系统调用移除一个链接(删除一个文件名),且如果此链接是指向文件的最后一个 链接,那么还将移除文件本身。
-
若 pathname 中指定的链接不存在,则 unlink()调用失败,并将 errno 置为 ENOENT。
-
unlink()系统调用不会对符号链接进行解引用操作,若 pathname 为符号链接,则移除链接 本身,而非链接指向的名称。
3. 仅当关闭所有文件描述符时,方可删除一个已打开的文件
4. 当移除指向文件的最后一个链接时,如果仍有进程持有指代该文件的打开文件描述符,那么 在关闭所有此类描述符之前,系统实际上将不会删除该文件。这一特性的妙用在于允许取消 对文件的链接,而无需担心是否有其他进程已将其打开。
五、更改文件名:rename()
-
借助于 rename()系统调用,既可以重命名文件,又可以将文件移至同一文件系统中的另一 目录。
#include <stdio.h> //将现有的一个路径名 oldpath 重命名为 newpath 参数所指定的路径名。
int rename(const char *oldpath, const char *newpath);
-
rename()调用仅操作目录条目,而不移动文件数据。改名既不影响指向该文件的其他硬链 接,也不影响持有该文件打开描述符的任何进程,因为这些文件描述符指向的是打开文件描 述,(在调用 open()之后)与文件名并无瓜葛。
-
以下规则适用与对 rename()的调用
-
newpath 已经存在,则将其覆盖。
-
若 newpath 与 oldpath 指向同一文件,则不发生变化(且调用成功)。
六、使用符号链接:symlink()和 readlink()
-
symlink()系统调用会针对由 target 所指定的路径名创建一个新的符号链接—linkpath。 (想移除符号链接,需使用 unlink()调用。)
#include <unistd.h>
int symlink(const char *target, const char *linkpath);
-
若 linkpath 中给定的路径名已然存在,则调用失败(且将 errno 置为 EEXIST)。由 filepath 指 定的路径名可以是绝对路径,也可以是相对路径。
2. 获取链接本身的内容,即其所指向的路径名
#include <unistd.h>
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
七、创建和移除目录:mkdir()和 rmdir()
-
mkdir()系统调用创建一个新目录。
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
-
mkdir()系统调用所创建的仅仅是路径名中的最后一部分。换言之,mkdir("aaa/bbb/ccc",mode) 仅当目录 aaa 和 aaa/bbb 已经存在的情况下才会成功。
2. rmdir()系统调用移除由 pathname 指定的目录,该目录可以是绝对路径名,也可以是相对 路径名。
#include <unistd.h>
int rmdir(const char *pathname);
八、移除一个文件或目录:remove()
-
remove()库函数移除一个文件或一个空目录
#include <stdio.h>
int remove(const char *pathname);
-
如果 pathname 是一文件,那么 remove()去调用 unlink();如果 pathname 为一目录,那么 remove()去调用 rmdir()。