本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议.

硬链接

为解决文件的共享使用, Linux系统引入了两种链接: 硬链接 (hard link)软链接(又称为符号链接,即soft link或symbolic link). 链接为Linux系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处.

  • 若一个inode号对应多个文件名, 则称这些文件为硬链接(硬链接就是同一个文件使用了多个别名), 对文件的修改, 会影响到所有相同inode的硬链接, 删除一个硬链接, 对其他硬链接没有影响

硬链接可由命令linkln创建

  • 硬链接只能对已存在的文件创建
  • 有相同的inode号
  • 不能对目录进行创建硬链接
  • 删除其中一个硬链接并不影响其他相同inode文件
1
2
3
4
5
6
7
8
9
10
# 格式: ln 源文件(已存在) 目标硬链接文件名
$ ln oldfile hardfile
$ link oldfile linkfile
# 查看inode号, 发现inode号相同(是文件的唯一标识, 后面会详细说)
$ ls -li| grep file
16134546 -rw-r--r-- 3 andrew_liu staff 25 7 6 16:56 hardfile
16134546 -rw-r--r-- 3 andrew_liu staff 25 7 6 16:56 linkfile
16134546 -rw-r--r-- 3 andrew_liu staff 25 7 6 16:56 oldfile

软链接

若文件用户数据块中存放的内容是另一文件的路径名, 则该文件就是软连接. 软链接就是一个普通文件, 只是数据块内容有点特殊(路径). 例如文件A是文件B的软链接, 读取文件A, 系统会通过路径访问文件B, 文件A依赖于文件B而存在, 如果删除了文件B,打开文件A就会报错, 如果重新添加文件, 会消除错误.

软链接和硬链接的最大不同在于, 软链接指向文件名, 硬链接指向inode

  • 软链接有自己的inode号以及用户数据块
  • 可对不存在的文件或目录创建软链接
  • 软链接可对文件或目录创建
  • 删除软链接并不影响被指向的文件, 但若被指向的原文件被删除,则相关软连接被称为死链接

软链接可由命令ln -s创建

1
2
3
4
5
$ ln -s oldfile softfile
$ ls -li| grep file
16134546 -rw-r--r-- 3 andrew_liu staff 25 7 6 16:56 oldfile
16135968 lrwxr-xr-x 1 andrew_liu staff 7 7 6 17:19 softfile -> oldfile

软链接创建时原文件的路径指向使用绝对路径较好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查找某一目录下oldfile的软链接
$ find /Users/andrew_liu/Downloads -lname oldfile
/Users/andrew_liu/Downloads/softfile
# 查找某一目录下oldfile的硬链接(包含自身)
$ find /Users/andrew_liu/Downloads -samefile oldfile
/Users/andrew_liu/Downloads/hardfile
/Users/andrew_liu/Downloads/linkfile
/Users/andrew_liu/Downloads/oldfile
# 列出某路径下下的所有软链接文件
$ find /Users/andrew_liu/Downloads -type l -ls

inode

inode是UNIX操作系统中的一种数据结构, 它包含了与文件系统中各个文件相关的一些重要信息

文件数据存储在文件块(block, 记录文件的真实内容)中, 而在inode中存储文件的元数据(文件的附加属性,如文件大小、创建时间、所有者等信息).

在UNIX中, 目录本身就是文件, 只是在它们的inode 中使用了一些附加的设置. 目录本质上就是一个包含了其他文件的文件.

查看完整的inode结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
struct inode {
...
/*
* Side effects; used during directory lookup.
*/
int32_t i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* inode文件编号 */
u_int32_t i_reclen; /* Size of found directory entry. *
union {
struct dirhash *dirhash; /* Hashing for large directories. */
daddr_t *snapblklist; /* Collect expunged snapshot blocks. */
} i_un
...
/*
* Copies from the on-disk dinode itself.
*/
u_int16_t i_mode; /* 文件读写执行权限 */
int16_t i_nlink; /* 文件硬链接数 */
u_int64_t i_size; /* 文件字节数 */
u_int32_t i_flags; /* 状态标识(chflags). */
int64_t i_gen; /* Generation number. */
u_int32_t i_uid; /* 文件拥有者ID */
u_int32_t i_gid; /* 文件组 */
...
};

操作系统用inode号码来识别不同的文件而不是文件名, 文件名只是对于用户友好

1
2
3
4
5
6
7
8
# 列出当前目录下所有inode和文件名
$ ls -i ./
# 查看每个硬盘分区的inode总数和已经使用的数量
$ df -i
# 查看某一文件挂载在那个文件系统下
$ df gitconfig

dotfiles配置备份

dotfiles是配置文件集合

1
2
3
4
5
6
7
8
9
10
11
# 将vim的配置文件放到dotfiles文件夹下, dotfiles是自定义的文件夹
$ mv .vim/vimrc ~/GitClone/dotfiles/vimrc
# 将zsh的配置文件放到dotfiles文件夹下
$ mv .zshrc ~/GitClone/dotfiles/zshrc
# 将git的配置文件放到dotfiles文件夹下
$ mv .gitconfig ~/GitClone/dotfiles/gitconfig
# 对dotfiles文件夹中的配置文件建立软链接
$ ln -s ~/GitClone/dotfiles/vimrc ~/.vim/vimrc
$ ln -s ~/GitClone/dotfiles/zshrc ~/.zshrc
$ ln -s ~/GitClone/dotfiles/gitconfig ~/.gitconfig

参考链接