Linux ln命令:创建文件链接

ln 是一个很神奇的命令,它可以创建一个文件的影子,也可以通过一个通道进入另一个地方。其实,所有的这些把戏都是通过软链接和硬链接来实现的。

链接也分软硬

软链接,全称是软链接文件,英文叫作 symbolic link。这类文件其实非常类似于 Windows 里的快捷方式,这个软链接文件(假设叫 VA)的内容,其实是另外一个文件(假设叫 B)的路径和名称,当打开 A 文件时,实际上系统会根据其内容找到并打开 B 文件。

使用格式
ln 源文件名称 硬链接文件名称
ln -s 源文件名称 软链接文件名称
建立属于你自己的目录链接

建立一般文件是常见的,那可以创建目录的链接吗?自从学会了 ln 命令之后,就像手里有了一把锤子,总觉得哪儿都是钉子。

[roc@roclinux ~]$ ls -F
tempdir/
 
[roc@roclinux ~]$ ln tempdir linkdir
ln: "tempdir": 不允许针对目录建立硬链接

我想硬链接一个目录 tempdir,但是报错了!是的,硬链接是不允许链接到目录的。至于原因,卖个关子,稍后再揭晓。
我们来尝试一下针对目录建立软链接,看看是否可以:

#尝试建立针对目录的软链接
[roc@roclinux ~]$ ln -s tempdir/ linkdir
[roc@roclinux ~]$ ls -li
总用量 4
2235009 lrwxrwxrwx 1 roc roc    8 31 00:32 linkdir -> tempdir/
2235011 drwxrwxr-x 2 roc roc 4096 31 00:30 tempdir
为什么 ln 不允许硬链接到目录

Linux 系统中的硬链接有两个限制:

  1. 不能跨越文件系统
  2. 不允许普通用户对目录作硬链接。

至于第一个限制,很好理解,而第二个就不那么好理解了。

我们对任何一个目录用 ls-l 命令都可以看到其链接数至少是 2,这也说明了系统中是存在基于目录的硬链接的,而且命令 ln-d(-d选项表示针对目录建立硬链接)也允许 root 用户尝试对目录作硬链接。这些都说明了系统限制对目录进行硬链接只是一个硬性规定,并不是逻辑上不允许或技术上不可行。那么操作系统为什么要进行这个限制呢?

这是因为,如果引入了对目录的硬连接就有可能在目录中引入循环链接,那么在目录遍历的时候系统就会陷入无限循环当中。也许有人会说,符号连接不也可以引入循环链接吗,那么为什么不限制目录的符号连接呢?

原因就在于,在 Linux 系统中,每个文件(目录也是文件)都对应着一个 inode 结构,其中 inode 数据结构中包含了文件类型(目录、普通文件、符号连接文件等)的信息,也就是说,操作系统在遍历目录时可以判断出其是否是符号连接。既然可以判断出它是否是符号连接,当然就可以采取一些措施来防范进入过大过深的循环层次,于是大部分系统会规定在连续遇到 8 个符号连接后就停止遍历。但是对于硬链接,由于操作系统中采用的数据结构和算法限制,目前是不能防范这种死循环的。

基于这样的考虑,系统不允许普通用户建立目录硬链接。

ln 命令的 -n 选项有点绕

n 命令里面有一个-n选项,它的官方解释是这样的:

-n, --no-dereference 
      treat destination that is a symlink to a directory as if it were a normal file.

这个选项理解起来的确有些难度,为此,我们模拟了一个操作过程,以便让大家能更好地理解。

第一步:建立两个文件夹 a 和 b。
[roc@roclinux ~]$ mkdir a b
[roc@roclinux ~]$ ls -F
a/  b/

第二步:针对 a 目录创建软链接 c。
[roc@roclinux ~]$ ln -s a c
[roc@roclinux ~]$ ls -li
总用量 8
2235012 drwxrwxr-x 2 roc roc 4096 31 00:47 a
2235013 drwxrwxr-x 2 roc roc 4096 31 00:47 b
2235009 lrwxrwxrwx 1 roc roc    1 31 00:48 c -> a

第三步:精髓就在这一步。
#我们再针对b目录创建软链接c, 造成了软链接c的重复定义
[roc@roclinux ~]$ ln -s b c
 
#软链接c并没有指向b, 上一条命令似乎并没有生效
[roc@roclinux ~]$ ls -li
总用量 8
2235012 drwxrwxr-x 2 roc roc 4096 31 00:48 a
2235013 drwxrwxr-x 2 roc roc 4096 31 00:47 b
2235009 lrwxrwxrwx 1 roc roc    1 31 00:48 c -> a
 
#我们进入到软链接c(也就是a目录)中看一看
[roc@roclinux ~]$ cd c/
 
#竟然发现了一个软链接b指向目录b, 而且是死链
[roc@roclinux c]$ ls -li
总用量 0
2235010 lrwxrwxrwx 1 roc roc 1 31 00:48 b -> b

可以看到,ln 会在 c 软链接目录(也就是 a 目录)里面创建一个 b 的软链接文件,且指向 b 目录,但很明显,这不是你的本意。

如果换成 ln-sn b c,那么结果就变了,我们一起来看。
#加上-n选项后, 系统发现了软链接重复定义的问题, 于是报错了

[roc@roclinux ~]$ ln -sn b c
ln: 创建符号链接 "c": 文件已存在
 
#我们使用-f(--force)来强制建立软链接, 看看效果
[roc@roclinux ~]$ ln -snf b c
 
#看, 原来指向a的符号链接c, 现在已经乖乖地指向b了
[roc@roclinux ~]$ ls -li
总用量 8
2235012 drwxrwxr-x 2 roc roc 4096 31 00:51 a
2235013 drwxrwxr-x 2 roc roc 4096 31 00:47 b
2235009 lrwxrwxrwx 1 roc roc    1 31 00:51 c -> b

这就是-n选项的作用,相信通过这样一个生动的例子,你应该可以理解下面这句话的含义了。
-n, --no-dereference
treat destination that is a symlink to a directory as if it were a normal file.

好了,有关 ln 命令的种种知识和示例,就讲到这里了。如果你对-n选项的作用理解得还不是非常透彻的话,就多看几遍吧,确实挺难理解的,哈哈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值