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后,软链接文件不能正常读取数据,但是硬链接文件可以正常使用,并且数据保持同步。当重命名文件改成源文件名后,软链接与硬链接都有效,且数据保持同步。


版权声明:著作权归作者所有。

相关推荐

Linux使用find查找大文件

Linux可以使用find命令来查找大文件。语法find <path> [-type <file-type>] -size +<size><unit> -type:指定文件类型,它有这些值d:目录f:普通文件l:链接b: 缓存块c: 非缓存字符p:  pipes

Linux uname命令的示例(系统管理命令)

说明打印系统相关信息,包括内核版本号、硬件架构、主机名称和操作系统类型等。语法uname [OPTION]... 常用选项-a,--all:显示全部的信息;-m,--machine:显示机器类型;-n,-nodename:显示在网络上的主机名称;-r,--release:显示操作系统的发行编号;-s,--sysname:显示操作系统名称;-v:显示操作系统的版本;-p,--process

Linux tee命令示例

功能从标准输入读取数据并写入到标准输出和文件。如果输出的文件不存在,则新建文件。语法tee [OPTION]... [FILE]... 选项:-a(--append): 追加输入内容到文件后面,不是覆盖。-i(--ignore-interrupts): 忽略中断信号。-help: 在线帮助。--version: 显示版本信息。示例使用管道

Linux使用grep查找文本所在的所有文件

显示所在文件及匹配到的文本grep -rin 'search' /path/  -r/-R:递归遍历目录-i:忽略大小写-n:显示出现在文件的行号仅显示所在文件grep -ril 'search' /path/ -l:显示所在的文件,而不是匹配到的文本包含/排除目录可以使用--exclude, --include, --excl

Linux shell命令监控文件的变化

1、tail:监控文件的实时更新tail -f logfile.log 2、watch:定时执行命令并输出命令内容,对于有改变的输出会以高亮的方式显示watch -n 10 -d ls -l /var/ -n:设置每隔多少秒执行指定的命令-d:设置执行的命令示例里是每10秒执行ls命令。

Git:.gitignore和.gitkeep文件的使用

.gitignore.gitignore,顾名思义,这个文件是用于列出那些让Git忽略,不被跟踪的文件,即排除在Git的版本控制外。可以使用*通配符匹配多个字符。忽略指定名称的文件# .gitignore示例,忽略test.txt文件  ################### test.txt 忽略指定后缀的文件# .gitignore示例,忽略后缀为.impl的文件