1. 概述
	1.1 命令功能
	1.2 man ln
	1.3 白话ln
2. 实测过程
	2.1 创建文件f1;硬连接f2, 指向f1;软连接f3, 指向f1。
	2.2 将 f1 改名为 f4,再查看文件内容:
	2.3 再次创建文件名f1的文件,内容是f1v2。分别查看几个文件内容。
	2.4 通过file, stat等命令查看文件
3. 查找链接
	3.1 查找硬链接
	3.2 查找软链接
4. 其他
	4.1 硬链接不能跨磁盘分区
	4.2 文件夹大小虚增假象
	4.3. 硬链接文件与原始文件没有区别

1. 概述

Linux ln(英文全拼:link files)命令是一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。 当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在 其它的目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间。
ln [参数][源文件或目录][目标文件或目录]

1.1 命令功能

Linux文件系统中,有所谓的链接(link),我们可以将其视为档案的别名,而链接又可分为两种 :  硬链接(hard link)与软链接(symbolic link),硬链接的意思是一个档案可以有多个名称, 而软链接的方式则是产生一个特殊的档案,该档案的内容是指向另一个档案的位置。 硬链接是存在同一个文件系统中,而软链接却可以跨越不同的文件系统。
不论是硬链接或软链接都不会将原本的档案复制一份,只会占用非常少量的磁碟空间。
 

1.2 man ln

ln [OPTION]... [-T] TARGET LINK_NAME
ln [OPTION]... TARGET
ln [OPTION]... TARGET... DIRECTORY
ln [OPTION]... -t DIRECTORY TARGET…
 
  • In the 1st form, create a link to TARGET with the name LINK_NAME.在第一种形式中,使用名称 [LINK_NAME] 创建指向 TARGET 的链接。
  • In the 2nd form, create a link to TARGET in the current directory.  在第二种形式中,在当前目录中创建指向 TARGET 的链接。
  • In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.  在第 3 和第 4 种形式中,创建指向 DIRECTORY 中每个 TARGET 的链接。
 
默认情况下创建硬链接,符号链接使用--symbolic。
默认情况下,每个目的地(新链接的名称)不应该已经存在。
创建硬链接时,每个 TARGET 都必须存在。
符号链接可以包含任意文本; 如果稍后解决,则相对链接将相对于其父目录进行解释。
 
--backup[=CONTROL] make a backup of each existing destination file 备份每个现有的目标文件
-b like --backup but does not accept an argument 类似 --backup 但不接受参数
-d, -F, --directory allow the superuser to attempt to hard link directories
(note: will probably fail due to system restrictions, even for the superuser)
允许超级用户尝试硬链接目录
(注意: 由于系统限制可能会失败,即使对于超级用户也是如此)
-f, --force remove existing destination files 删除现有的目标文件
-i, --interactive prompt whether to remove destinations 提示是否删除目的地
-L, --logical dereference TARGETs that are symbolic links 取消引用作为符号链接的 TARGET
-n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory 如果 LINK_NAME 是指向目录的符号链接,则将其视为普通文件
-P, --physical make hard links directly to symbolic links 直接建立到符号链接的硬链接
-r, --relative create symbolic links relative to link location 创建相对于链接位置的符号链接
-s, --symbolic make symbolic links instead of hard links 制作符号链接而不是硬链接
-S, --suffix=SUFFIX override the usual backup suffix 覆盖通常的备份后缀
-t, --target-directory=DIRECTORY specify the DIRECTORY in which to create the links 指定创建链接的目录
-T, --no-target-directory treat LINK_NAME as a normal file always 始终将 LINK_NAME 视为普通文件
-v, --verbose print name of each linked file 每个链接文件的打印名称
--help display this help and exit 显示此帮助并退出
--version output version information and exit 输出版本信息并退出
     
  The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through the VERSION_CONTROL environment variable. Here are the values:
备份后缀为“~”,除非使用 --suffix 或 SIMPLE_BACKUP_SUFFIX 设置。
可以通过 --backup 选项或 VERSION_CONTROL 环境变量选择版本控制方法。 以下是值:
none, off never make backups (even if --backup is given) 从不进行备份(即使给出了 --backup )
numbered, t make numbered backups 进行编号备份
existing, nil numbered if numbered backups exist, simple otherwise 如果存在编号备份,则编号,否则简单
simple, never always make simple backups 总是做简单的备份
  Using -s ignores -L and -P.
Otherwise, the last option specified controls behavior when a TARGET is a symbolic link, defaulting to -P.
使用 -s 会忽略 -L 和 -P。
否则,当 TARGET 是符号链接时,指定的最后一个选项控制行为,默认为 -P。

1.3 白话ln

  • 硬链接(hard link) [ln TARGET LINK_NAME] 硬链接直接指向文件的inode编号,所以建立成功后和原始文件名平起平坐,互不影响,不管是删除,改名,还是移动其中任何一个都不会影响另外一个。也因为指向inode,所以建立硬链接不能跨磁盘分区。
  • 软连接(symbolic link) [ln -s TARGET LINK_NAME] 软连接也叫符号链接,就像windows下的快捷方式,只是存储了原始文件的路径而已。因此,原始文件若改名,删除或移动了位置,都会导致这个软链接失效。也因为保存的是路径,所以可以随意跨磁盘分区。
 

2. 实测过程

2.1 创建文件f1;硬连接f2, 指向f1;软连接f3, 指向f1。

 % touch f1 
 % ln f1 f2  
 % ln -s f1 f3
列出文件信息:
 % ls -li 
 13669980 -rw-r--r--  2 tom  staff    0 10  9 19:58 f1 
 13669980 -rw-r--r--  2 tom  staff    0 10  9 19:58 f2 
 13669986 lrwxr-xr-x  1 tom  staff    2 10  9 19:58 f3 -> f1
向文件f1内写入信息,并分别查看3个文件内容:
 % echo "I am f1" >> f1  
 % cat f1 
I am f1  
 % cat f2 
I am f1  
 % cat f3 
I am f1
f1, f2公用一个inode节点,相当于一个人有2个名字。 f3是个快捷方式指向f1。  查看3个文件的内容都是一样的,应为只有一个实际的文件。
 

2.2 将 f1 改名为 f4,再查看文件内容:

 % mv f1 f4  
 % cat f1   
 cat: f1: No such file or directory  
 % cat f2  
  I am f1  
 % cat f3   
 cat: f3: No such file or directory  
 % cat f4 
 I am f1
f1因为被改名,不存在了,所以访问无效; f2, 没变;f4是f1改名而来,内容不变; f3, 指向不存在的f1,访问无效。
列出文件信息:
 % ls -li   
 13669980 -rw-r--r--  2 tom  staff    8 10  9 20:00 f2 
 13669986 lrwxr-xr-x  1 tom  staff    2 10  9 19:58 f3 -> f1 
 13669980 -rw-r--r--  2 tom  staff    8 10  9 20:00 f4
f4, f2公用一个inode节点,相当于一个人有2个名字。 f3是个快捷方式指向不存在的f1路径,成为无效文件。 
 

2.3 再次创建文件名f1的文件,内容是f1v2。分别查看几个文件内容。

 % echo "I am f1v2" > f1  
 % cat f1 
 I am f1v2  
 % cat f2 
 I am f1  
 % cat f3 
 I am f1v2  
 % cat f4 
 I am f1
列出文件信息:
 % ls -li 
 13670265 -rw-r--r--  1 tom  staff   10 10  9 20:07 f1 
 13669980 -rw-r--r--  2 tom  staff    8 10  9 20:06 f2 
 13669986 lrwxr-xr-x  1 tom  staff    2 10  9 19:58 f3 -> f1 
 13669980 -rw-r--r--  2 tom  staff    8 10  9 20:06 f4
f4, f2公用一个inode节点,相当于一个人有2个名字。 f3是个快捷方式指向f1路径,成为新文件的快捷方式。 
 

2.4 通过file, stat等命令查看文件

 % file f1 
 f1: ASCII text  
 % file f2 
 f2: ASCII text  
 % file f3 
 f3: ASCII text  
 % file f4 
 f4: ASCII text
 
 % stat f1 
 16777241 13670265 -rw-r--r-- 1 tom staff 0 10 "Oct  9 20:07:55 2022" "Oct  9 20:07:54 2022" "Oct  9 20:07:54 2022" "Oct  9 20:07:54 2022" 4096 8 0 f1  
 % stat f2 
 16777241 13669980 -rw-r--r-- 2 tom staff 0 8 "Oct  9 20:06:54 2022" "Oct  9 20:06:52 2022" "Oct  9 20:06:52 2022" "Oct  9 19:58:07 2022" 4096 8 0 f2  
 % stat f3 
 16777241 13669986 lrwxr-xr-x 1 tom staff 0 2 "Oct  9 19:58:28 2022" "Oct  9 19:58:28 2022" "Oct  9 19:58:28 2022" "Oct  9 19:58:28 2022" 4096 0 0 f3  
 % stat f4 
 16777241 13669980 -rw-r--r-- 2 tom staff 0 8 "Oct  9 20:06:54 2022" "Oct  9 20:06:52 2022" "Oct  9 20:06:52 2022" "Oct  9 19:58:07 2022" 4096 8 0 f4
 

3. 查找链接

3.1 查找硬链接

查找思路,通过相同的inode查找,且不会跨分区的特点,只需要在本分区范围查找即可。
 -inum nTrue if the file has inode number n.
 -samefile nameTrue if the file is a hard link to name.   If the command option -L is specified, it is also true if the file is a symbolic link and points to name.
 % find /Users/tom/Music -inum "13669980" > /dev/null
 % find . -inum 13669980   
 ./f4 
 ./f2 
 ./f5 
 ./f6
 
% find . -samefile f4   
./f4 
./fg/f5 
./ff/f2 
./f6
 
 % find . -samefile f4 -exec ls -l {} \; 
 -rw-r--r--  4 tom  staff  8 10  9 20:06 ./f4 
 -rw-r--r--  4 tom  staff  8 10  9 20:06 ./fg/f5 
 -rw-r--r--  4 tom  staff  8 10  9 20:06 ./ff/f2 
 -rw-r--r--  4 tom  staff  8 10  9 20:06 ./f6
 

3.2 查找软链接

查找思路,通过类型l,原始文件名称查找,要从根目录下全盘搜索才不会漏掉。
 % find . -type l 
 ./f3 
 ./g3 
 ./f7
 
 % find . -type l -exec ls -l {} \;   
 lrwxr-xr-x  1 tom  staff  2 10  9 19:58 ./f3 -> f1 
 lrwxr-xr-x  1 tom  staff  2 10  9 22:04 ./g3 -> g2 
 lrwxr-xr-x  1 tom  staff  2 10  9 21:07 ./f7 -> f1
 
 % find . -type l -exec ls -l {} \; |grep f1 
 lrwxr-xr-x  1 tom  staff  2 10  9 19:58 ./f3 -> f1 
 lrwxr-xr-x  1 tom  staff  2 10  9 21:07 ./f7 -> f1
 

4. 其他

4.1 硬链接不能跨磁盘分区

跨分区无法创建硬链接,每个分区的inode不重复,但不同分区的inode都是个自重新编号。
ln: failed to create hard link ‘o2’ => ‘/home/tom/o2’; Invalid cross-device link

4.2 文件夹大小虚增假象

在一个文件夹里,给一个文件做10个硬链接,查看文件属性,这些文件除了名称,其他都一样,文件夹的大小也增大到10倍。
但若使用 du 命令,就能看到真实的文件夹大小了。

4.3 硬链接文件与原始文件没有区别

访问或修改原始文件或任何一个关联的硬链接文件,使用stat查看所有相关文件,都会得到一样的结果,从这里每法分辨是通过那个名称访问或修改的文件。只能从系统日志找到入口名称。
 % stat -x f9
 File: "f9"   Size: 8
 FileType: Regular File 
 Mode: (0644/-rw-r--r--)         Uid: (  501/     tom)  Gid: (   20/   staff) 
 Device: 1,25   Inode: 13669980    Links: 5 
 Access: Mon Oct 10 04:44:44 2022 
 Modify: Sun Oct  9 20:06:52 2022 
 Change: Mon Oct 10 04:44:43 2022  
 Birth: Sun Oct  9 19:58:07 2022