发布于 1年前

Linux文件硬链接和软链接ln命令的使用

ln 命令用于给文件创建链接,根据 Linux 系统存储文件的特点,链接的方式分为以下 2 种:

  • 软链接:类似于 Windows 系统中给文件创建快捷方式,即产生一个特殊的文件,该文件用来指向另一个文件,此链接方式同样适用于目录。
  • 硬链接:我们知道,文件的基本信息都存储在 inode 中,而硬链接指的就是给一个文件的 inode 分配多个文件名,通过任何一个文件名,都可以找到此文件的 inode,从而读取该文件的数据信息

ln 命令的基本格式如下:

[root@localhost ~]# ln [选项] 源文件 目标文件

选项:

  • -s:建立软链接文件。如果不加 "-s" 选项,则建立硬链接文件;
  • -f:强制。如果目标文件已经存在,则删除目标文件后再建立链接文件;

创建硬链接:

[root@localhost ~]# touch cangls
[root@localhost ~]# ln /root/cangls /tmp
#建立硬链接文件,目标文件没有写文件名,会和原名一致
#也就是/tmp/cangls 是硬链接文件

创建软链接:

[root@localhost ~]# touch bols
[root@localhost ~]# In -s /root/bols /tmp
#建立软链接文件

这里需要注意,软链接文件的源文件必须写成绝对路径,而不能写成相对路径(硬链接没有这样的要求);否则软链接文件会报错。

软链接与硬链接的占用磁盘空间情况

软链接,相当于创建了一个快捷方式;而硬链接,以文件副本的形式存在,但不占用实际空间。

通俗的说,软链接,链接源文件没有了,链接文件相当于找不到家了,无法正常使用;而硬链接由于是以副本形式存在,链接源文件没有了,仍旧可以正常使用。

[root@localhost test_ln]# du -h --max-depth=1
6.2G    .
[root@localhost test_ln]# ls -lh ping.log
-rw-r--r--. 1 root root 3.4G May 10 02:00 ping.log
[root@localhost test_ln]# ln -s ping.log ping22.log
[root@localhost test_ln]# ln -d ping.log ping23.log
[root@localhost test_ln]# ls -lh ping*
lrwxrwxrwx. 1 root root    8 May 10 02:03 ping22.log -> ping.log
-rw-r--r--. 2 root root 3.4G May 10 02:00 ping23.log
-rw-r--r--. 2 root root 3.4G May 10 02:00 ping.log
-rw-r--r--. 1 root root 2.9G May 10 02:00 ping_tmp.log
[root@localhost test_ln]# du -h --max-depth=1
6.2G    .
[root@localhost test_ln]# head -n 5 ping.log ping22.log ping23.log 
==> ping.log <==
PING 192.168.153.1 (192.168.153.1) 56(84) bytes of data.
64 bytes from 192.168.153.1: icmp_seq=1 ttl=128 time=0.395 ms
64 bytes from 192.168.153.1: icmp_seq=2 ttl=128 time=0.329 ms
64 bytes from 192.168.153.1: icmp_seq=3 ttl=128 time=0.253 ms
64 bytes from 192.168.153.1: icmp_seq=4 ttl=128 time=0.271 ms
==> ping22.log <==
PING 192.168.153.1 (192.168.153.1) 56(84) bytes of data.
64 bytes from 192.168.153.1: icmp_seq=1 ttl=128 time=0.395 ms
64 bytes from 192.168.153.1: icmp_seq=2 ttl=128 time=0.329 ms
64 bytes from 192.168.153.1: icmp_seq=3 ttl=128 time=0.253 ms
64 bytes from 192.168.153.1: icmp_seq=4 ttl=128 time=0.271 ms
==> ping23.log <==
PING 192.168.153.1 (192.168.153.1) 56(84) bytes of data.
64 bytes from 192.168.153.1: icmp_seq=1 ttl=128 time=0.395 ms
64 bytes from 192.168.153.1: icmp_seq=2 ttl=128 time=0.329 ms
64 bytes from 192.168.153.1: icmp_seq=3 ttl=128 time=0.253 ms
64 bytes from 192.168.153.1: icmp_seq=4 ttl=128 time=0.271 ms
[root@localhost test_ln]# rm -f ping.log
[root@localhost test_ln]# du -h --max-depth=1
6.2G    .
[root@localhost test_ln]# rm -f ping22.log 
[root@localhost test_ln]# du -h --max-depth=1
6.2G    .
[root@localhost test_ln]# rm -f ping23.log 
[root@localhost test_ln]# du -h --max-depth=1
2.9G    .

如上,找了一个3.4G大小的文件ping.log,分别创建了软链接文件ping22.log与硬链接文件ping23.log。通过du -h --max-depth=1命令,查看当前目录占用空间,发现并没有增加空间占用,说明软链接与硬链接都不占用空间(可能不准确,至少从感知上是这样)。接着开始删除文件,先删除源文件ping.log,发现删除后,磁盘占用空间不变。接着删除软链接文件ping22.log,磁盘占用空间不变。最后删除硬链接文件ping23.log,发现磁盘占用空间少了近3.3G。可以推断,当软链接源文件删除后,软链接的快捷方式也就失效,磁盘空间释放。但是当硬链接源文件删除后,磁盘空间占用并不会释放,必须源文件与硬链接文件都删除后,才会释放磁盘空间。

源文件删除

[root@localhost test_ln]# echo "ping.log" > ping.log 
[root@localhost test_ln]# ln -s ping.log ping30.log
[root@localhost test_ln]# ln -d ping.log ping31.log
[root@localhost test_ln]# tail ping.log ping30.log ping31.log 
tail: inotify cannot be used, reverting to polling
==> ping.log <==
ping.log
==> ping30.log <==
ping.log
==> ping31.log <==
ping.log
[root@localhost test_ln]# rm -f ping.log 
[root@localhost test_ln]# tail ping.log ping30.log ping31.log 
tail: inotify cannot be used, reverting to polling
tail: cannot open `ping.log' for reading: No such file or directory
tail: cannot open `ping30.log' for reading: No such file or directory
==> ping31.log <==
ping.log
[root@localhost test_ln]# echo "rewrite to ping.log" > ping.log
[root@localhost test_ln]# tail ping.log ping30.log ping31.log 
tail: inotify cannot be used, reverting to polling
==> ping.log <==
rewrite to ping.log
==> ping30.log <==
rewrite to ping.log
==> ping31.log <==
ping.log

重新创建被删除的源文件ping.log,软链接文件ping30.log恢复链接,且数据同步,链接依旧有效。而硬链接文件ping31.log,则还是之前数据,与最初建立源文件的ping.log数据内容不一致。也就是说,硬链接会在源文件删除后,链接会失效。

移动至其它目录

[root@localhost test_ln]# mv temp/ping.log .
[root@localhost test_ln]# echo "move ping.log back. " >> ping.log
[root@localhost test_ln]# head ping.log
ping.log
move ping.log back. 
[root@localhost test_ln]# tail ping5.log ping6.log
tail: inotify cannot be used, reverting to polling
==> ping5.log <==
ping.log
move ping.log back. 
==> ping6.log <==
ping.log
move ping.log back. 

被移动的源文件,重新移动至原来的目录,软链接与硬链接可以正常读取数据,并且数据是同步的。说明,源文件被移动后,链接关系可在文件移动回来后恢复。但是软链接不能读取,硬链接是可以。既然如此,那么文件被移动后,硬链接是不是一直有效呢?

[root@localhost test_ln]# echo "ping.log" > ping.log
[root@localhost test_ln]# ln -d ping.log ping8.log
[root@localhost test_ln]# mv ping.log temp/
[root@localhost test_ln]# head ping8.log
ping.log
[root@localhost test_ln]# echo "ping.log move to temp directory" >> temp/ping.log 
[root@localhost test_ln]# tail temp/ping.log ping8.log
==> temp/ping.log <==
ping.log
ping.log move to temp directory
==> ping8.log <==
ping.log
ping.log move to temp directory

事实证明:软链接与硬链接的源文件被移动后,链接并没有失效。此时,软链接由于是一个“快捷方式”,找不到文件而无法正常使用,而硬链接是有一个副本,源文件并没有丢失,仍可正常使用,并且数据正常同步。当文件移回原目录时,软链接与硬链接都正常。

源文件重命名

[root@localhost test_ln]# echo "ping.log" > ping.log
[root@localhost test_ln]# ln -s ping.log ping20.log
[root@localhost test_ln]# ln -d ping.log ping21.log
[root@localhost test_ln]# tail ping.log ping20.log ping21.log 
tail: inotify cannot be used, reverting to polling
==> ping.log <==
ping.log
==> ping20.log <==
ping.log
==> ping21.log <==
ping.log
[root@localhost test_ln]# mv ping.log ping_new.log
[root@localhost test_ln]# tail ping_new.log ping20.log ping21.log 
tail: inotify cannot be used, reverting to polling
==> ping_new.log <==
ping.log
tail: cannot open `ping20.log' for reading: No such file or directory
==> ping21.log <==
ping.log
[root@localhost test_ln]# echo "ping.log rename to ping_new.log">>ping_new.log 
[root@localhost test_ln]# tail ping_new.log ping20.log ping21.log 
tail: inotify cannot be used, reverting to polling
==> ping_new.log <==
ping.log
ping.log rename to ping_new.log
tail: cannot open `ping20.log' for reading: No such file or directory
==> ping21.log <==
ping.log
ping.log rename to ping_new.log
[root@localhost test_ln]# mv ping_new.log ping.log
[root@localhost test_ln]# tail ping_new.log ping20.log ping21.log 
tail: inotify cannot be used, reverting to polling
tail: cannot open `ping_new.log' for reading: No such file or directory
==> ping20.log <==
ping.log
ping.log rename to ping_new.log
==> ping21.log <==
ping.log
ping.log rename to ping_new.log
[root@localhost test_ln]# echo "rename back" >> ping.log 
[root@localhost test_ln]# tail ping_new.log ping20.log ping21.log 
tail: inotify cannot be used, reverting to polling
tail: cannot open `ping_new.log' for reading: No such file or directory
==> ping20.log <==
ping.log
ping.log rename to ping_new.log
rename back
==> ping21.log <==
ping.log
ping.log rename to ping_new.log
rename back

如上,软链接文件ping20.log,硬链接文件ping21.log文件的源文件为ping.log。当重命名源文件为ping_new.log后,软链接文件不能正常读取数据,但是硬链接文件可以正常使用,并且数据保持同步。当重命名文件改成源文件名后,软链接与硬链接都有效,且数据保持同步。

©2020 edoou.com   京ICP备16001874号-3