我们知道 ln 用于创建连接文件,ln命令的选项有很多,此处主要理解 -snf三个
-s --symbolic比较容易,有-s时表示创建软连接,没有-s时,表示创建硬链接
-f --force 强行删除任何已存在的目标文件
-n --no-dereference 把符号连接的目的目录视为一般文件
硬链接:只能对文件创建硬链接,不能对目录创建硬链接
软连接:既能对文件创建软连接,也能对目录创建软连接
ln -s 源文件名 连接文件名
ln -s 源目录名 连接目录名
对目录创建软连接和对文件创建软连接有所不同
如果要创建的连接文件名已经存在,就会报错
[vagrant@localhost test1]$ touch a b [vagrant@localhost test1]$ ll total 0 -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:06 a -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:06 b [vagrant@localhost test1]$ ln -s a b //因为想要创建的连接文件名b已经存在,所以报错, 如果此处加上-f,则不会报错,而是会删除原有的b文件,并创建新的b连接文件,达到覆盖的效果 ln: failed to create symbolic link ‘b’: File exists [vagrant@localhost test1]$
[vagrant@localhost test1]$ ln -s a c //因为想要创建的连接文件名c不存在,所以创建成功
[vagrant@localhost test1]$ ll
total 0
-rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:06 a
-rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:06 b
lrwxrwxrwx 1 vagrant vagrant 1 Feb 5 16:08 c -> a
如果要创建的连接目录名已经存在,并不会报错,而是在已存在的目录文件内部创建一个以源目录名为名的的连接文件并指向其自身,而不是指向源目录
这种情况不知道有什么作用,感觉像是一种bug似的
而如果要创建的连接目录名不存在,则会创建连接目录指向源目录
[vagrant@localhost test1]$ mkdir d1 d2 [vagrant@localhost test1]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:19 d1 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:19 d2 [vagrant@localhost test1]$ ln -s d1 d2 //d2目录已经存在,并没有报错,从ll d2命令可以看出, d2目录内部生成了以源目录d1为名的连接文件d1并指向了其自己 [vagrant@localhost test1]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:19 d1 drwxrwxr-x 2 vagrant vagrant 16 Feb 5 16:19 d2 [vagrant@localhost test1]$ ll d2 // total 0 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:19 d1 -> d1 //d2目录内部生成了以源目录d1为名的连接文件d1并指向了其自己 [vagrant@localhost test1]$ ll /d2/d1 ls: cannot access /d2/d1: No such file or directory [vagrant@localhost test1]$ ln -s d1 d3 //d3目录不存在,会在当前目录下生成连接目录d3来直线源目录d1 [vagrant@localhost test1]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:19 d1 drwxrwxr-x 2 vagrant vagrant 16 Feb 5 16:19 d2 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:20 d3 -> d1 [vagrant@localhost test1]$
由以上可以看出对目录创建软连接和对文件创建软连接是不同的
假设已经由文件a和文件b,当对创建a文件的软连接为c后,又想对b创建软连接,连接文件名也为c,只需要加上-f即可
[vagrant@localhost test2]$ touch a b [vagrant@localhost test2]$ ln -s a c [vagrant@localhost test2]$ ll total 0 -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:32 a -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:32 b lrwxrwxrwx 1 vagrant vagrant 1 Feb 5 16:32 c -> a [vagrant@localhost test2]$ ln -s b c //c文件已经存在,报错,要加上-f ln: failed to create symbolic link ‘c’: File exists [vagrant@localhost test2]$ ln -sf b c [vagrant@localhost test2]$ ll total 0 -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:32 a -rw-rw-r-- 1 vagrant vagrant 0 Feb 5 16:32 b lrwxrwxrwx 1 vagrant vagrant 1 Feb 5 16:32 c -> b
不同于文件,假设已经有目录d1和目录d2,当对创建d1目录的软连接为d3后,又想对目录d2创建软连接,连接目录名也为d3,则除了加上-f外,需要加上-n ,-n的作用就是不要将连接目录d3看作连接目录,而是将其看作一个普通的文件
[vagrant@localhost test2]$ mkdir d1 d2 [vagrant@localhost test2]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d1 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d2 [vagrant@localhost test2]$ ln -s d1 d3 //创建的d1的连接目录d3 [vagrant@localhost test2]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d1 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d2 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:40 d3 -> d1 //创建成功 [vagrant@localhost test2]$ ln -s d2 d3 //想创建目录d2的连接,也为d3来覆盖原来的连接目录d3,有下面可以看出,没有成功,而是在d1目录中创建了连接目录d2指向了其自身 [vagrant@localhost test2]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 16 Feb 5 16:41 d1 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d2 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:40 d3 -> d1 //没有创建d2的连接目录,还是d1的连接目录 [vagrant@localhost test2]$ ll d3 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:40 d3 -> d1 [vagrant@localhost test2]$ ll d1 total 0 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:41 d2 -> d2 //d1 目录中多了d2连接文件 [vagrant@localhost test2]$ ln -sn d2 d3 //有-n 将d3看成普通文件而不是连接目录,由于已经存在,报错 ln: failed to create symbolic link ‘d3’: File exists [vagrant@localhost test2]$ ln -snf d2 d3 //除了-n,再加上-f,就可以删除旧的d1的连接目录d3,并生成新的d2的连接目录d3 [vagrant@localhost test2]$ ll total 0 drwxrwxr-x 2 vagrant vagrant 16 Feb 5 16:41 d1 drwxrwxr-x 2 vagrant vagrant 6 Feb 5 16:40 d2 lrwxrwxrwx 1 vagrant vagrant 2 Feb 5 16:43 d3 -> d2 [vagrant@localhost test2]$
总结:以上说了一堆代码,主要是一步步测试,简而言之
如果想要用一个新的连接目录来覆盖旧的连接目录,需要加上 -n 和 -f选项, -n用于将连接目录看作一个普通的文件,-f用于删除旧的连接目录
ln -snf d2 d3
如果没有-n, 就会将d3看作连接目录,而d3有指向d1,所以上面的命令就相当于 ln -sf d2 d1, 所以使用ll d1命令,就看到了在d1目录中多了连接目录d2
-n 选项的使用实例
centos7中安装了python2.7和python3.6,python连接文件指向的是2.7的,所以执行python命令,就是只用2.7的,但如果要默认使用3.6的,就需要创建新的连接文件python指向3.6的
ln -snf /usr/bin/python3.6 /usr/bin/python //当然此处为连接文件而不是连接目录,个人觉得可以省去-n选项
[root@stg-asset-app01 tasks]# ll /usr/bin | grep python lrwxrwxrwx 1 root root 27 Jun 28 2019 futurize -> /usr/bin/python2.7-futurize lrwxrwxrwx 1 root root 27 Jun 28 2019 futurize-2 -> /usr/bin/python2.7-futurize lrwxrwxrwx 1 root root 27 Jun 28 2019 futurize-2.7 -> /usr/bin/python2.7-futurize lrwxrwxrwx 1 root root 29 Jun 28 2019 pasteurize -> /usr/bin/python2.7-pasteurize lrwxrwxrwx 1 root root 29 Jun 28 2019 pasteurize-2 -> /usr/bin/python2.7-pasteurize lrwxrwxrwx 1 root root 29 Jun 28 2019 pasteurize-2.7 -> /usr/bin/python2.7-pasteurize lrwxrwxrwx 1 root root 14 Feb 5 15:04 python -> /bin/python2.7 lrwxrwxrwx. 1 root root 9 May 16 2019 python2 -> python2.7 -rwxr-xr-x. 1 root root 7216 Apr 9 2019 python2.7 -rwxr-xr-x 1 root root 304 May 3 2019 python2.7-futurize -rwxr-xr-x 1 root root 308 May 3 2019 python2.7-pasteurize lrwxrwxrwx 1 root root 9 Feb 4 11:03 python3 -> python3.6 -rwxr-xr-x 2 root root 11408 Aug 8 02:29 python3.6 -rwxr-xr-x 2 root root 11408 Aug 8 02:29 python3.6m