0%

关于硬链接、软链接和快捷方式

关于硬链接、软链接和快捷方式

硬链接、软链接

在UNIX/Linux文件系统中,文件类型分为普通文件、目录文件、设备文件和符号链接等几类。每个文件的存储包含三部分,分别是文件名(filename)、文件说明(inode)、数据块(data block)。打开文件时,通过文件名找到inode id,然后找到inode,根据inode信息找到数据块。

关于inode,参考阮一峰的【理解inode】,其中阐述比较详细,也介绍了软硬链接。

系统允许不同文件名,对应到同一inode,这就是所谓的硬链接(hard links),可使用ln命令创建。此外,inode中会记录指向自己文件名的个数,方便删除操作,即个数为0才会回收数据块。

软链接(symlink)又称符号链接是一种特殊类型的文件,它指向源文件,甚至指向其他文件系统(远端)的文件,当然所指向的文件也可能被删了,此时类似于空指针,可使用ln -s 命令创建。需要注意,软链接可用相对地址或绝对地址,如果相对地址的软链接,移动之后可能会失效。删除目录软链接时,切记rm smlink而不是rm smlink/后者会

目录不允许创建硬链接,试想,如果不同目录下的子目录指向同一个目录(inode),可能会存在子目录中包含父目录的情况,造成目录死循环,如cp等命令会失效。这是因为硬链接太逼真了,无法区分这个是源文件还是硬链接,都是平等的,目前文件系统的设计,无法处理这种情况;但是,可以对目录建立软链接,它只是一种特殊类型的文件,里面存储了源文件的路径,在遍历目录时只把它当成一种文件来看待。需要注意的是,在复制目录时,是可以对目录下的文件均复制为硬链接的,cp -al,但这和对目录创建硬链接是有本质区别的。此处可参考如:

Why are hard links to directories not allowed in UNIX/Linux?
Why are hard links not allowed for directories?

应用场景

硬链接

硬链接的使用较少,有一句话如下

You generally should not use hard links anyway

也就是不建议使用硬链接,确实应用场景不多,但存在即合理,有时用其拷贝文件防止误删。

软链接

我们通常使用的都是软链接,它是操作系统级别的,大部分情况会应用程序被当成实实在在真实文件/目录一样,以下应用场景皆为这个原理。Linux系统中就存在大量软链接,常见的有

文件软链接

  1. 比如某包安装目录下的可执行文件,会被软链接到$PATH中,如/usr/bin

  2. 重命名。一些库文件.so等,会通过软链接去掉后面的版本,方便动态编译使用,经常遇到一些开源包编译不通过,缺少相关动态链接库,需要这样加个软链接解决一下,如常见的libz

    1
    2
    3
    libz.so -> libz.so.1.2.7  
    libz.so.1 -> libz.so.1.2.7
    libz.so.1.2.7
  3. 将某些无用文件指向 /dev/null,如某日志ln -s /dev/null /data/temp.log

目录软链接

  1. 分区容量扩容,某分区容量吃紧,可以通过将其他分区的目录软链接过来使用。或者文件移动过去,再软链接回来保持原路径不变,既节省了容量,也免除了路径更改带来的配置修改。
  2. 在版本升级中,更改路径名之后,会建立软链接到旧目录兼容旧版本。
  3. 将目录的软链接放到网盘目录中,网盘会同步此目录。

Windows中建立软链接

使用mklink在Windows中建立软硬链接,默认给文件建立软链接,如果给目录建立软链接,需要加/D参数,硬链接需要/H参数。此外NTFS格式的磁盘还特有一种Junction,和软链接类似,且只能用于文件夹。

关于复制和剪切软硬链接

弄清了软硬链接的原理,对复制和粘贴的结果会有一个预期,Linux下复制和剪切均符合预期,windows下复制软链接时会复制源目标,变为普通文件或目录,对文件夹Junction的剪切,会使其变为普通文件夹,并且把子文件全剪切过来。

快捷方式

最后说说快捷方式,它是更高层一点的应用,不同于软硬链接是文件管理和操作系统层面的东西。Windows环境下,它是一种后缀名为.lnk的普通文件,被系统的桌面环境,资源管理器(explorer.exe)解析。它类似于软链接,但是功能更丰富些,可以增加启动参数,快捷键等。

Linux的桌面系统也有类似Windows快捷方式的东西。如Unity、KDE、GNOME,它们使用Desktop Entry 文件标准来描述程序启动配置信息,后缀为.desktop的文本文件,文本格式如下

1
2
3
4
5
6
7
8
9
10
11
$ cat goagent-gtk.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=GoAgent GTK
Comment=GoAgent GTK Launcher
Categories=Network;Proxy;
Exec=/usr/bin/env python "/home/zz_zigzag/software/agent/goagent-gtk.py"
Icon=/home/zz_zigzag/software/agent/goagent-logo.png
Terminal=false
StartupNotify=true

统一放在/usr/share/applications下被桌面系统索引。

参考连接|附录

Symbolic link
理解 Linux 的硬链接与软链接
Windows的四种链接方式
阮一峰的【理解inode】
深入理解操作系统原理之文件系统