ln 是 Linux 中常见的命令,本意 link
,可用于创建软链接和硬链接。
用法概览:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[root@centos test]# ln --help
用法:ln [选项]... [-T] 目标 链接名 (第一种格式)
或:ln [选项]... 目标 (第二种格式)
或:ln [选项]... 目标... 目录 (第三种格式)
或:ln [选项]... -t 目录 目标... (第四种格式)
In the 1st form, create a link to TARGET with the name LINK_NAME.
In the 2nd form, create a link to TARGET in the current directory.
In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
Create hard links by default, symbolic links with --symbolic.
By default, each destination (name of new link) should not already exist.
When creating hard links, each TARGET must exist. Symbolic links
can hold arbitrary text; if later resolved, a relative link is
interpreted in relation to its parent directory.
Mandatory arguments to long options are mandatory for short options too.
--backup[=CONTROL] 为每个已存在的目标文件创建备份文件
-b 类似--backup,但不接受任何参数
-d, -F, --directory 创建指向目录的硬链接(只适用于超级用户)
-f, --force 强行删除任何已存在的目标文件
-i, --interactive prompt whether to remove destinations
-L, --logical dereference TARGETs that are symbolic links
-n, --no-dereference treat LINK_NAME as a normal file if
it is a symbolic link to a directory
-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
-v, --verbose print name of each linked file
--help 显示此帮助信息并退出
--version 显示版本信息并退出
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:
none, off 不进行备份(即使使用了--backup 选项)
numbered, t 备份文件加上数字进行排序
existing, nil 若有数字的备份文件已经存在则使用数字,否则使用普通方式备份
simple, never 永远使用普通方式备份
Using -s ignores -L and -P. Otherwise, the last option specified controls
behavior when a TARGET is a symbolic link, defaulting to -P.
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
请向<http://translationproject.org/team/zh_CN.html> 报告ln 的翻译错误
要获取完整文档,请运行:info coreutils 'ln invocation'
创建链接
有如下一个文件:
1
2
[root@centos test]# ll a/b/c.txt
-rw-r--r--. 1 root root 6 1月 9 23:27 a/b/c.txt
创建硬链接
1
2
3
4
5
[root@centos test]# ln a/b/c.txt c.hardlink
[root@centos test]# ll
总用量 8
drwxr-xr-x. 3 root root 4096 1月 9 23:27 a
-rw-r--r--. 2 root root 6 1月 9 23:27 c.hardlink
创建软链接(符号链接)
需要使用 -s
选项:
1
2
3
4
5
6
[root@centos test]# ln -s a/b/c.txt c.softlink
[root@centos test]# ll
总用量 8
drwxr-xr-x. 3 root root 4096 1月 9 23:27 a
-rw-r--r--. 2 root root 6 1月 9 23:27 c.hardlink
lrwxrwxrwx. 1 root root 9 1月 10 09:43 c.softlink -> a/b/c.txt
有一点可以注意到,软链接文件的权限是所有用户可读写执行,但实际使用时会被原文件的权限限制。
如果链接文件已存在的话,再创建会提示已存在:
1
2
[root@centos test]# ln a/b/c.txt c.hardlink
ln: 无法创建硬链接"c.hardlink": 文件已存在
备份并覆盖
如果要覆盖原链接文件可以使用 -b
参数,覆盖之前会先备份,如下 c.hardlink~
即为备份的文件:
1
2
3
4
5
6
7
[root@centos test]# ln -b a/b/c.txt c.hardlink
[root@centos test]# ll
总用量 12
drwxr-xr-x. 3 root root 4096 1月 9 23:27 a
-rw-r--r--. 3 root root 6 1月 9 23:27 c.hardlink
-rw-r--r--. 3 root root 6 1月 9 23:27 c.hardlink~
lrwxrwxrwx. 1 root root 9 1月 10 09:43 c.softlink -> a/b/c.txt
交互式使用
如果交互式使用,可以使用 -i
参数:
1
2
[root@centos test]# ln -i a/b/c.txt c.hardlink
ln:是否替换"c.hardlink"? n
查看详细创建过程
可以使用 -v
选项:
1
2
3
4
5
6
7
8
9
[root@centos test]# ln -v a/b/c.txt C.hardlink
"C.hardlink" => "a/b/c.txt"
[root@centos test]# ll
总用量 16
drwxr-xr-x. 3 root root 4096 1月 9 23:27 a
-rw-r--r--. 4 root root 6 1月 9 23:27 c.hardlink
-rw-r--r--. 4 root root 6 1月 9 23:27 c.hardlink~
-rw-r--r--. 4 root root 6 1月 9 23:27 C.hardlink
lrwxrwxrwx. 1 root root 9 1月 10 09:43 c.softlink -> a/b/c.txt
删除链接
对于普通文件的软链接、硬链接来说,直接使用 rm linkname
即可。
对于目录软链接有一点要注意,
1
2
3
4
5
6
7
8
9
10
[root@centos test]# mkdir A
[root@centos test]# echo PHP is the best > A/php.txt
[root@centos test]# tree
bash: tree: 未找到命令
[root@centos test]#
[root@centos test]# ln -s A dirA.softlink
[root@centos test]# ls -lih
总用量 4.0K
130314 drwxr-xr-x. 2 root root 4.0K 1月 10 12:08 A
130316 lrwxrwxrwx. 1 root root 1 1月 10 12:08 dirA.softlink -> A
链接名后不能加 /
,会删除目标目录下所有的文件:
1
2
3
4
5
[root@centos test]# rm -f dirA.softlink/
rm: 无法删除"dirA.softlink/": 是一个目录
[root@centos test]# rm -rf dirA.softlink/
[root@centos test]# ls -lih A
总用量 0
删除目录软链接,直接使用链接名:
1
2
3
4
[root@centos test]# rm -f dirA.softlink
[root@centos test]# ls -lih
总用量 4.0K
130314 drwxr-xr-x. 2 root root 4.0K 1月 10 12:08 A
软硬链接区别
我们创建一个新文件:
1
2
3
4
[root@centos test]# echo hello linux > a/b/hello.txt
[root@centos test]# ls -lih a/b
总用量 4.0K
130316 -rw-r--r--. 1 root root 12 1月 10 10:31 hello.txt
1
2
3
4
5
6
7
[root@centos test]# ln a/b/hello.txt hello.hardlink
[root@centos test]# ln -s a/b/hello.txt hello.softlink
[root@centos test]# ls -lih
总用量 8.0K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 12 1月 10 10:31 hello.hardlink
130317 lrwxrwxrwx. 1 root root 13 1月 10 10:32 hello.softlink -> a/b/hello.txt
链接文件权限
从上面的输出中可以看到: 硬链接的文件权限为 rw-r--r--
; 软链接的文件权限为 rwxrwxrwx
,对所有用户开放了所有权限;
文件类型
从上面的输出中可以看到: 硬链接的文件类型是 -
,即普通文件; 软链接的文件类型是 l
,即链接文件;
inode
前面看到源文件的 inode 值为 13016,硬链接的 inode 值与源文件的相同,而软链接的 inode 值与源文件的不同,为 13017,即是个新文件,仅仅记录了源文件的绝对路径。这也是软链接、硬链接最本质的不同。
硬链接与源文件共用同一个 inode,即同一磁盘区域,我们查看源文件的引用计数 2
也能查看到:
1
2
3
[root@centos test]# ls -lih a/b/
总用量 4.0K
130316 -rw-r--r--. 2 root root 12 1月 10 10:31 hello.txt
如果再创建一个硬链接,可以发现源文件和硬链接的引用计数增加了,均为3:
1
2
3
4
5
6
7
8
9
10
[root@centos test]# ln a/b/hello.txt hello.hardlink2
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 3 root root 12 1月 10 10:31 hello.hardlink
130316 -rw-r--r--. 3 root root 12 1月 10 10:31 hello.hardlink2
130317 lrwxrwxrwx. 1 root root 13 1月 10 10:32 hello.softlink -> a/b/hello.txt
[root@centos test]# ls -lih a/b/
总用量 4.0K
130316 -rw-r--r--. 3 root root 12 1月 10 10:31 hello.txt
如果更新源文件,根据软链接、硬链接查看时也是会同步的:
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@centos test]# echo hello linux >> a/b/hello.txt
[root@centos test]# cat a/b/hello.txt
hello linux
hello linux
[root@centos test]# cat hello.hardlink
hello linux
hello linux
[root@centos test]# cat hello.hardlink2
hello linux
hello linux
[root@centos test]# cat hello.softlink
hello linux
hello linux
如果将原文件删除,会发现软硬链接处理方式的不同:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@centos test]# rm -f a/b/hello.txt
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink2
130317 lrwxrwxrwx. 1 root root 13 1月 10 10:32 hello.softlink -> a/b/hello.txt
[root@centos test]# cat hello.hardlink
hello linux
hello linux
[root@centos test]# cat hello.hardlink2
hello linux
hello linux
[root@centos test]# cat hello.softlink
cat: hello.softlink: 没有那个文件或目录
删除源文件后,硬链接的引用计数-1,仍然能够通过硬链接访问原始内容,但通过软链接就无法访问了。实际上,源文件并没有从磁盘上删除,只是引用计数减少了。
如果重新写入同名的源文件,新写入的文件与之前的文件不是同一个文件,下面可以看到 inode 值不同:
1
2
3
4
5
6
7
8
9
10
11
[root@centos test]# echo hello world >> a/b/hello.txt
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink2
130317 lrwxrwxrwx. 1 root root 13 1月 10 10:32 hello.softlink -> a/b/hello.txt
[root@centos test]#
[root@centos test]# ls -lih a/b
总用量 4.0K
130318 -rw-r--r--. 1 root root 12 1月 10 11:14 hello.txt
如果通过软链接编辑删除的源文件呢?
我们先删掉刚刚新建的文件
1
[root@centos test]# rm -f a/b/hello.txt
通过软链接修改软链接指向的文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@centos test]# echo hello linux >> hello.softlink
[root@centos test]# ls -lih a/b
总用量 4.0K
130318 -rw-r--r--. 1 root root 12 1月 10 11:18 hello.txt
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink2
130317 lrwxrwxrwx. 1 root root 13 1月 10 10:32 hello.softlink -> a/b/hello.txt
[root@centos test]#
[root@centos test]# cat a/b/hello.txt
hello linux
[root@centos test]# echo hello java >> a/b/hello.txt
[root@centos test]# cat a/b/hello.txt
hello linux
hello java
[root@centos test]# cat hello.softlink
hello linux
hello java
我们发现创建出了新的 a/b/hello.txt
,新的文件与软链接保持了链接关系。
如果通过硬链接编辑删除的源文件呢?
我们先删除刚刚新增的 a/b/hello.txt
1
2
3
4
5
6
[root@centos test]# rm -f hello.softlink a/b/hello.txt
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink
130316 -rw-r--r--. 2 root root 24 1月 10 11:08 hello.hardlink2
通过硬链接编辑删除的源文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@centos test]# echo hello PHP >> hello.hardlink
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 2 root root 34 1月 10 11:27 hello.hardlink
130316 -rw-r--r--. 2 root root 34 1月 10 11:27 hello.hardlink2
[root@centos test]#
[root@centos test]# ls -lih a/b
总用量 0
[root@centos test]# cat hello.hardlink
hello linux
hello linux
hello PHP
[root@centos test]# cat hello.hardlink2
hello linux
hello linux
hello PHP
我们可以看到,硬链接指向的文件内容同样进行了更新,但没有恢复出源文件。
如果想恢复源文件呢?
我们可以再创建一次硬链接:
1
2
3
4
5
6
7
8
9
[root@centos test]# ln hello.hardlink a/b/hello.txt
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink2
[root@centos test]# ls -lih a/b
总用量 4.0K
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.txt
因为硬链接可以视作给文件创建了一个别名,不管本名还是别名指向的都是同一块磁盘数据。
目录
不能给目录创建硬链接:
1
2
[root@centos test]# ln a dir_a.hardlink
ln: "a": 不允许将硬链接指向目录
可以给目录创建软链接:
1
2
3
4
5
6
7
[root@centos test]# ln -s a dir_a.softlink
[root@centos test]# ls -lih
总用量 12K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130317 lrwxrwxrwx. 1 root root 1 1月 10 11:39 dir_a.softlink -> a
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink2
链接的内容
硬链接“链接”的其实是磁盘块数据,前面删除源文件硬链接仍然能够查看已经体现出来了。
软链接“链接”的其实是文件路径,这个我们再深化理解下:
我们创建两个文件:
1
2
[root@centos test]# echo iphone13 > apple.txt
[root@centos test]# echo mi12 > xiaomi.txt
给 apple.txt 创建软链接:
1
2
3
4
5
6
7
8
9
10
11
12
[root@centos test]# ln -s apple.txt apple.softlink
[root@centos test]# ls -lih
总用量 20K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130320 lrwxrwxrwx. 1 root root 9 1月 10 11:51 apple.softlink -> apple.txt
130318 -rw-r--r--. 1 root root 9 1月 10 11:50 apple.txt
130317 lrwxrwxrwx. 1 root root 1 1月 10 11:39 dir_a.softlink -> a
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink2
130319 -rw-r--r--. 1 root root 5 1月 10 11:51 xiaomi.txt
[root@centos test]# cat apple.softlink
iphone13
删除源文件,用别的文件重命名为源文件的名称:
1
2
3
4
5
6
7
8
9
10
11
12
[root@centos test]# rm -f apple.txt
[root@centos test]# cat apple.softlink
cat: apple.softlink: 没有那个文件或目录
[root@centos test]# mv xiaomi.txt apple.txt
[root@centos test]# ls -lih
总用量 16K
130314 drwxr-xr-x. 3 root root 4.0K 1月 9 23:27 a
130320 lrwxrwxrwx. 1 root root 9 1月 10 11:51 apple.softlink -> apple.txt
130319 -rw-r--r--. 1 root root 5 1月 10 11:51 apple.txt
130317 lrwxrwxrwx. 1 root root 1 1月 10 11:39 dir_a.softlink -> a
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink
130316 -rw-r--r--. 3 root root 34 1月 10 11:27 hello.hardlink2
最后通过软链接查看下最新的内容:
1
2
[root@centos test]# cat apple.softlink
mi12
可以看到软链接链接到了目标文件路径的最新内容。
软硬链接应用场景
软链接
适用于可执行程序的快捷方式
硬链接
备份重要文件,避免误删,误删后还可以恢复。