ln 命令用来创建链接,默认地,它会创建硬链接。如果加上 -s 选项,它会创建符号链接( 或软链接 )。
ln 语法如下
ln [OPTION]... TARGET... DIRECTORY
ln [OPTION]... -t DIRECTORY TARGET...
ln [OPTION]... TARGET
ln [OPTION]... [-T] TARGET LINKNAME
这四个语法其实都是一个意思,都表示在指定目录下为 TARGET 创建链接。
前两种语法已经明显指定的了目录名。第三种语法省略了目录名,其实指的就是当前目录。最后一个语法中,LINKNAME 已经暗含了目录名,并且还指定了链接的名子。
创建硬链接
硬链接的创建非常直观明了
$ ln hello hello_hard
这个命令是在当前目录下为 hello 文件创建一个名为 hello_hard 的硬链接。
$ ln hello dir1/
这个命令是在 dir1 目录下,为当前目录下的 hello 文件创建硬链接。
一个硬链接其实就是一个文件的另外一个名子而已,修改硬链接就等于修改文件本身。但是硬链接有两个缺点
- 一个硬链接不能关联它所在文件系统之外的文件。这是说一个链接不能关联 与链接本身不在同一个磁盘分区上的文件。
- 一个硬链接不能关联一个目录。
然而这些缺点,都是可以通过符号链接弥补的。
创建符号连接
创建符号连接相比于创建硬链接,稍微复杂一点。
$ ln -s hello hello_symbolic
这个命令会在当前目录下为 hello 文件创建一个符号链接,修改 hello_symbolic 其实就是修改 hello 文件。
如果我们想在另外一个目录下创建 hello 文件的符号链接呢?就会有一点不同
ln -s hello dir1/hello_symbolic
这个命令会在 dir1 目录下为当前目录下的 hello 文件创建符号链接 hello_symbolic,但是这个用法是错误的。最直观的验证方式是,当你修改 dir1 目录下的 hello_symbolic 文件时,并不会影响当前目录下的 hello 文件。我们可以查看下 dir1 目录下的 hello_symbolic 文件,如下
$ ls -l dir1
lrwxrwxrwx 1 david david 5 9月 30 11:40 hello_symbolic -> hello
在 Ubuntu 下,这个输出结果中,hello_symbolic 和 hello 都被标红了,表示是一个无效的符号链接。输出结果hello_symbolic -> hello
的意思是,符号链接 hello_symbolic
指向了当前文件目录下的 hello 文件,这很显示是错误的,它应该指向父目录的 hello 文件。
创建相对路径的符号链接
因此纠正下前面创建符号链接的命令
$ ls -l
$ -rw-r--r-- 3 david david 14 9月 30 11:40 hello
$
$ ln -s ../hello dir1/hello_symbolic
$
$ ls -l dir1
lrwxrwxrwx 1 david david 8 9月 30 13:19 hello_symbolic -> ../hello
从 ls -l
命令可以看出,hello 文件在当前目录下,但是创建符号链接的命令却使用了 ../hello
表示符号链接指定的文件,真的特别难受。
这种创建符号链接的方式叫做创建相对路径的符号链接。符号链接指向的文件必须相对于符号链接位置的文件。通常,创建相对路径的符号链接是首先进入目标目录,然后再创建符号链接,这样就顺畅多了
$ cd dir1
$
$ ln -s ../hello
$
$ ls -l
lrwxrwxrwx 1 david david 8 9月 30 13:25 hello -> ../hello
创建绝对路径的符号链接
相对路径的符号链接有个缺点,目录包含符号链接的目录移动了,那么符号链接就失效了。因此我们可以创建一个绝对路径的符号链接。
linux $ ln -s ~+/hello dir1/
linux $ ls -l dir1/
总用量 0
lrwxrwxrwx 1 david david 30 9月 30 13:37 hello -> /home/david/linux/hello
dir1 下的符号链接现在指向了一个绝对路径,这样就不用再害怕包含符号链接的目录被移动了。
~+/hello
利用的是 shell 的波浪线展开特性,它被展开为一个绝对路径。
工作经验
工作中,项目都是多人协作的,因此要避免在项目中创建绝对路径的符号链接,因为如果你创建的绝对路径的符号链接,通过仓库更新被他人使用时,就会出现问题,因此在这种情况下,最好的方式是使用相对路径的符号链接。
删除符号链接
无论是符号链接,还是硬链接,都可以使用如下语法删除链接
rm link_name
对于一个指向目录的符号链接来说,有个比较有意思的事情
$ ln -s dir1 dir1_symbolic
$
$ rm -r dir1_symbolic/
rm: 无法删除'dir1_symbolic/': 不是目录
$
$ rm dir1_symbolic/
rm: 无法删除'dir1_symbolic/': 是一个目录
$
可以看到,如果在执行 rm 命令时,在符号链接名 dir_symbolic
后面加上一个斜线,那么是无法删除符号链接的,正确的做法就是直接使用名子删除即可,也就是rm dir1_symbolic
。