リンクを使用して、Linux ファイル システム内の複数の場所からファイルにアクセスし、日常の作業を容易にする方法を学びます。
Linux ファイル システムには、ハード リンクとソフト リンクという 2 種類のリンクがあります。この 2 つは大きく異なりますが、どちらも同様の問題を解決するために使用されます。どちらも 1 つのファイルに対する複数のディレクトリ エントリ (参照) へのアクセスを提供しますが、実装はまったく異なります。すべてがファイルであるため、リンクの力により Linux ファイル システムに柔軟性が与えられます。
たとえば、一部のプログラムの実行には特定のバージョンのライブラリが必要であることがわかりました。アップグレードされたライブラリを使用して古いライブラリを置き換えると、プログラムがクラッシュし、古いバージョンのライブラリが見つからないというメッセージが表示されます。多くの場合、ライブラリ名の唯一の変更はバージョン番号です。直感的に、私はプログラムに新しいライブラリ リンクを追加し、古いライブラリ名にちなんで名前を付けました。プログラムを再度起動してみましたが、正常に実行されました。プログラムはゲームであり、誰もがそれを理解しており、すべてのプレイヤーはゲームを続けるために最善を尽くします。
実際には、ほとんどすべてのアプリケーション リンク ライブラリは共通の命名規則を使用しています。リンク名にはメジャー バージョン番号が含まれ、リンクが指すファイルのファイル名にはマイナー バージョン番号も含まれます。別の例として、Linux ファイル システム仕様に準拠するために、プログラムに必要なファイルの一部が、あるディレクトリから別のディレクトリに移動されますが、システムは、新しい場所を取得できないプログラムとの下位互換性を確保するために、これらのファイルへのリンクを古いディレクトリに保存します。これらのファイルのうち。 /lib64 ディレクトリの長いリストを作成すると、この例がたくさん見つかります。
リーリー/lib64 ディレクトリ内のいくつかのリンク
上記の /lib64 ディレクトリのリストでは、ファイル モードの最初の文字 l (小文字の l) は、これがソフト リンク (シンボリック リンクとも呼ばれる) であることを示しています。
「Linux の EXT4 ファイル システムの歴史、機能、ベスト プラクティス」の記事で、各ファイルにはファイルの場所情報など、ファイルに関する情報が含まれる i ノードがあるという事実について説明しました。上記の記事の図 2 は、inode を指す単一のディレクトリ エントリを示しています。各ファイルには、ファイル情報を記述する i ノードを指すディレクトリ エントリが少なくとも 1 つあります。ディレクトリ エントリはハード リンクであるため、各ファイルには少なくとも 1 つのハード リンクがあります。
以下の図 1 に示すように、複数のディレクトリ エントリが同じ i ノードを指します。これらのディレクトリ エントリはハード リンクです。 3 つのディレクトリ エントリでチルダ (~) の省略形を使用しました。これはユーザー ディレクトリの規則であるため、この例ではチルダは /home/user に相当します。 4 番目のディレクトリ エントリはまったく異なるディレクトリ /home/shared であることに注意してください。これは、このコンピュータ上のユーザーの共有ファイル ディレクトリである可能性があります。
ハード リンクは単一のファイル システムに制限されます。ここでの「ファイル システム」とは、特定のマウント ポイント (この場合は /home) にマウントされたパーティションまたは論理ボリュームを指します。これは、inode 番号が各ファイル システムで一意であるためです。 /var や /opt などの別のファイル システムでは、/home と同じ i ノード番号が存在します。
すべてのハード リンクはファイルのメタ情報を含む単一の i ノードをポイントしているため、これらの属性 (所有権、アクセス許可、i ノードへのハード リンクの数など) はファイルの一部です。これらの特性はハード リンクごとにあります。なし違う。これは、ファイルが持つ一連のプロパティです。これらのファイルを区別できるのは、inode 情報に含まれるファイル名だけです。同じディレクトリ内の単一のファイル/inode へのハード リンクは、同じディレクトリ内に重複したファイル名が存在できないという事実に基づいて、異なるファイル名を持つ必要があります。
ファイル内のハード リンクの数は、ls -l を使用して表示できます。実際のノード番号を表示したい場合は、ls -li コマンドを使用できます。
ハード リンクとソフト リンク (シンボリック リンク シンボリック リンクとも呼ばれる) の違いは、ハード リンクはファイルに属する i ノードを直接指すのに対し、ソフト リンクはディレクトリ エントリ、つまりハード リンクを直接指すことです。ソフト リンクは、ファイルの i ノードではなくファイルへのハード リンクを指すため、i ノード番号に依存せず、異なるファイル システム、パーティション、論理ボリューム間で動作することができます。
ソフト リンクの欠点は、ソフト リンクが指すハード リンクが削除または名前変更されると、ソフト リンクが無効になることです。ソフト リンクはまだ存在しますが、それが指すハード リンクはもう存在しません。幸いなことに、ls コマンドは、リスト内の壊れたソフト リンクを赤い背景に白いテキストで強調表示できます。
我认为最容易理解链接用法及其差异的方法是动手搭建一个项目。这个项目应以非超级用户的身份在一个空目录下进行。我创建了 ~/temp 目录做这个实验,你也可以这么做。这么做可为项目创建一个安全的环境且提供一个新的空目录让程序运作,如此以来这儿仅存放和程序有关的文件。
首先,在你要进行实验的目录下为该项目中的任务创建一个临时目录,确保当前工作目录(PWD)是你的主目录,然后键入下列命令。
mkdir temp
使用这个命令将当前工作目录切换到 ~/temp。
cd temp
实验开始,我们需要创建一个能够链接到的文件,下列命令可完成该工作并向其填充内容。
du -h > main.file.txt
使用 ls -l 长列表命名确认文件正确地创建了。运行结果应类似于我的。注意文件大小只有 7 字节,但你的可能会有 1~2 字节的变动。
[dboth@david temp]$ ls -l total 4 -rw-rw-r-- 1 dboth dboth 7 Jun 13 07:34 main.file.txt
在列表中,文件模式串后的数字 1 代表存在于该文件上的硬链接数。现在应该是 1 ,因为我们还没有为这个测试文件建立任何硬链接。
硬链接创建一个指向同一 inode 的新目录项,当为文件添加一个硬链接时,你会看到链接数目的增加。确保当前工作目录仍为 ~/temp。创建一个指向 main.file.txt 的硬链接,然后查看该目录下文件列表。
[dboth@david temp]$ ln main.file.txt link1.file.txt [dboth@david temp]$ ls -l total 8 -rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 link1.file.txt -rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 main.file.txt
目录中两个文件都有两个链接且大小相同,时间戳也一样。这就是有一个 inode 和两个硬链接(即该文件的目录项)的一个文件。再建立一个该文件的硬链接,并列出目录清单内容。你可以建立硬链接: link1.file.txt 或 main.file.txt。
[dboth@david temp]$ ln link1.file.txt link2.file.txt ; ls -l total 16 -rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link1.file.txt -rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link2.file.txt -rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 main.file.txt
注意,该目录下的每个硬链接必须使用不同的名称,因为同一目录下的两个文件不能拥有相同的文件名。试着创建一个和现存链接名称相同的硬链接。
[dboth@david temp]$ ln main.file.txt link2.file.txt ln: failed to create hard link 'link2.file.txt': File exists
显然不行,因为 link2.file.txt 已经存在。目前为止我们只在同一目录下创建硬链接,接着在临时目录的父目录(你的主目录)中创建一个链接。
[dboth@david temp]$ ln main.file.txt ../main.file.txt ; ls -l ../main* -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
上面的 ls 命令显示 main.file.txt 文件确实存在于主目录中,且与该文件在 temp 目录中的名称一致。当然它们不是不同的文件,它们是同一文件的两个链接,指向了同一文件的目录项。为了帮助说明下一点,在 temp 目录中添加一个非链接文件。
[dboth@david temp]$ touch unlinked.file ; ls -l total 12 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
使用 ls 命令的 i 选项查看 inode 的硬链接号和新创建文件的硬链接号。
[dboth@david temp]$ ls -li total 12 657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt 657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt 657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt 657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
注意上面文件模式左边的数字 657024 ,这是三个硬链接文件所指的同一文件的 inode 号,你也可以使用 i 选项查看主目录中所创建的链接的节点号,和该值相同。而那个只有一个链接的 inode 号和其他的不同,在你的系统上看到的 inode 号或许不同于本文中的。
接着改变其中一个硬链接文件的大小。
[dboth@david temp]$ df -h > link2.file.txt ; ls -li total 12 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt 657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
现在所有的硬链接文件大小都比原来大了,因为多个目录项都链接着同一文件。
下个实验在我的电脑上会出现这样的结果,是因为我的 /tmp 目录在一个独立的逻辑卷上。如果你有单独的逻辑卷或文件系统在不同的分区上(如果未使用逻辑卷),确定你是否能访问那个分区或逻辑卷,如果不能,你可以在电脑上挂载一个 U 盘,如果上述方式适合你,你可以进行这个实验。
试着在 /tmp 目录中建立一个 ~/temp 目录下文件的链接(或你的文件系统所在的位置)。
[dboth@david temp]$ ln link2.file.txt /tmp/link3.file.txt ln: failed to create hard link '/tmp/link3.file.txt' => 'link2.file.txt': Invalid cross-device link
为什么会出现这个错误呢? 原因是每一个单独的可挂载文件系统都有一套自己的 inode 号。简单的通过 inode 号来跨越整个 Linux 文件系统结构引用一个文件会使系统困惑,因为相同的节点号会存在于每个已挂载的文件系统中。
有时你可能会想找到一个 inode 的所有硬链接。你可以使用 ls -li 命令。然后使用 find 命令找到所有硬链接的节点号。
[dboth@david temp]$ find . -inum 657024 ./main.file.txt ./link1.file.txt ./link2.file.txt
注意 find 命令不能找到所属该节点的四个硬链接,因为我们在 ~/temp 目录中查找。 find 命令仅在当前工作目录及其子目录中查找文件。要找到所有的硬链接,我们可以使用下列命令,指定你的主目录作为起始查找条件。
[dboth@david temp]$ find ~ -samefile main.file.txt /home/dboth/temp/main.file.txt /home/dboth/temp/link1.file.txt /home/dboth/temp/link2.file.txt /home/dboth/main.file.txt
如果你是非超级用户,没有权限,可能会看到错误信息。这个命令也使用了 -samefile 选项而不是指定文件的节点号。这个效果和使用 inode 号一样且更容易,如果你知道其中一个硬链接名称的话。
如你刚才看到的,不能跨越文件系统边界创建硬链接,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接给出了这个问题的解决方案。虽然它们可以达到相同的目的,但它们是非常不同的,知道这些差异是很重要的。
让我们在 ~/temp 目录中创建一个符号链接来开始我们的探索。
[dboth@david temp]$ ln -s link2.file.txt link3.file.txt ; ls -li total 12 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt 658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt -> link2.file.txt 657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt 657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
拥有节点号 657024 的那些硬链接没有变化,且硬链接的数目也没有变化。新创建的符号链接有不同的 inode 号 658270。 名为 link3.file.txt 的软链接指向了 link2.file.txt 文件。使用 cat 命令查看 link3.file.txt 文件的内容。符号链接的 inode 信息以字母 l (小写字母 l)开头,意味着这个文件实际是个符号链接。
上例中软链接文件 link3.file.txt 的大小只有 14 字节。这是文本内容 link3.file.txt 的大小,即该目录项的实际内容。目录项 link3.file.txt 并不指向一个 inode ;它指向了另一个目录项,这在跨越文件系统建立链接时很有帮助。现在试着创建一个软链接,之前在 /tmp 目录中尝试过的。
[dboth@david temp]$ ln -s /home/dboth/temp/link2.file.txt /tmp/link3.file.txt ; ls -l /tmp/link* lrwxrwxrwx 1 dboth dboth 31 Jun 14 21:53 /tmp/link3.file.txt -> /home/dboth/temp/link2.file.txt
当你删除硬链接或硬链接所指的文件时,需要考虑一些问题。
首先,让我们删除硬链接文件 main.file.txt。注意指向 inode 的每个目录项就是一个硬链接。
[dboth@david temp]$ rm main.file.txt ; ls -li total 8 657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt 657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link2.file.txt 658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt -> link2.file.txt 657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
main.file.txt 是该文件被创建时所创建的第一个硬链接。现在删除它,仍然保留着原始文件和硬盘上的数据以及所有剩余的硬链接。要删除原始文件,你必须删除它的所有硬链接。
现在删除 link2.file.txt 硬链接文件。
[dboth@david temp]$ rm link2.file.txt ; ls -li total 8 657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt 658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt -> link2.file.txt 657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 main.file.txt 657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
注意软链接的变化。删除软链接所指的硬链接会使该软链接失效。在我的系统中,断开的链接用颜色高亮显示,目标的硬链接会闪烁显示。如果需要修复这个损坏的软链接,你需要在同一目录下建立一个和旧链接相同名字的硬链接,只要不是所有硬链接都已删除就行。您还可以重新创建链接本身,链接保持相同的名称,但指向剩余的硬链接中的一个。当然如果软链接不再需要,可以使用 rm 命令删除它们。
unlink 命令在删除文件和链接时也有用。它非常简单且没有选项,就像 rm 命令一样。然而,它更准确地反映了删除的基本过程,因为它删除了目录项与被删除文件的链接。
我用过这两种类型的链接很长一段时间后,我开始了解它们的能力和特质。我为我所教的 Linux 课程编写了一个实验室项目,以充分理解链接是如何工作的,并且我希望增进你的理解。
(题图: Paul Lewin,Opensource.com 修改。 CC BY-SA 2.0)
作者简介:
戴维.布斯 - 戴维.布斯是 Linux 和开源倡导者,居住在北卡罗莱纳的罗列 。他在 IT 行业工作了四十年,为 IBM 工作了 20 多年的 OS/2。在 IBM 时,他在 1981 年编写了最初的 IBM PC 的第一个培训课程。他为 RedHat 教授过 RHCE 班,并曾在 MCI Worldcom、思科和北卡罗莱纳州工作。他已经用 Linux 和开源软件工作将近 20 年了。
以上がLinux ファイルリンクの使用の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。