ハードリンクとは何かを知っています しかし、なぜそれらを使用するのですか?ハードリンクのユーティリティは何ですか?
ハードリンクの主な利点は、ソフトリンクと比較して、サイズや速度のペナルティがないことです。ソフトリンクは、通常のファイルアクセスに加えて、追加の間接層です。カーネルはファイルを開くときにリンクを逆参照する必要があり、これには少し時間がかかります。リンクはまた、リンクのテキストを保持するために、ディスク上に少量のスペースを取ります。これらのペナルティは、ファイルシステムの構造そのものに組み込まれているため、ハードリンクでは発生しません。
これを確認するために私が知っている最善の方法は次のとおりです。
$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../
ls
の-i
オプションは、ファイルの inode番号 を提供します。上記の例を作成したシステムで、偶然にもiノード番号1069765のディレクトリにいますが、特定の値は関係ありません。これは、特定のファイル/ディレクトリを識別する一意の値です。
これは、サブディレクトリに移動し、..
と呼ばれるdifferentファイルシステムエントリを見ると、同じiノード番号が前に得た。これは、MS-DOSおよびWindowsで発生するように、シェルが..
を解釈しているため、発生していません。 Unixファイルシステムでは、..
は実際のディレクトリエントリです。これは、前のディレクトリを指すハードリンクです。
ハードリンクは、ファイルシステムのディレクトリを結びつける腱です。昔々、Unixにはハードリンクがありませんでした。これらは、Unixの元の フラットファイルシステム を階層ファイルシステムに変換するために追加されました。
(これについての詳細は 「/」に「..」エントリがあるのはなぜですか? を参照してください。)
Unixシステムでは、いくつかの異なるコマンドが同じ実行可能ファイルによって実装されることもいくらか一般的です。 Linuxではもうそうではないようですが、私が過去に使用したシステムでは、cp
、mv
およびrm
はすべて同じ実行可能ファイルでした。考えてみれば理にかなっています。ボリューム間でファイルを移動する場合、それは実質的にはコピーとそれに続く削除なので、mv
はすでに他の2つのコマンドの機能を実装する必要がありました。実行可能ファイルは、呼び出された名前が渡されるため、提供する操作を判別できます。
組み込みLinuxで一般的な別の例は BusyBox です。これは 数十 のコマンドを実装する単一の実行可能ファイルです。
ほとんどのファイルシステムでは、ユーザーがディレクトリへのハードリンクを作成することは許可されていません。 .
および..
エントリは、通常はカーネルの一部であるファイルシステムコードによって自動的に管理されます。制限が存在するのは、ディレクトリハードリンクの作成方法と使用方法に注意しないと、深刻なファイルシステムの問題を引き起こす可能性があるためです。これは、ソフトリンクが存在する多くの理由の1つです。同じリスクはありません。
非常に便利なハードリンクの1つの使用法は、rsyncと組み合わせた増分バックアップです。それは多くのスペースを節約し、復元手順を本当に簡単にします。私はサーバーでのバックアップにそのアプローチを使用しています。
少し時間をかけて この説明 を読んでください。
そのウィキペディアのページを読んだ後、「なぜ私はそれらを使用するのか」という質問である場合、ハードリンクが何であるか理解できません。
linkは、ディスク上のブロックを指すディレクトリエントリです。つまり、システム上のすべてのファイルに少なくとも1つのリンクがあります。ファイルをrm
する場合、実際のシステムコールはunlink()
です。ディレクトリエントリを削除します。ディスク上のブロックは変更されていませんが、リンクが失われているため、ファイルはディレクトリリストから削除されています。
個人的にハードリンクを使用することはないかもしれませんが、それらはシステム全体に存在します。例えば:
$ ls -li /bin | grep 53119771
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bunzip2
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzcat
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzip2
あなたはそれを見ることができますbunzip2
、bzcat
およびbzip
はすべて同じiノードを使用します。本質的には、3つの名前を持つ1つのファイルです。あなたはファイルの3つのコピーを持つことができますが、なぜですか?不必要にディスク容量を使い果たすだけです。
用途はいくつもあります。それらを使用して、ファイルベースのロックを作成します。 link(2)システムコールは、他のほとんどのシステムコールとは異なり、アトミックです。
もう1つの用途はrsnapshot内であり、ハードリンクを使用して時間の経過とともにバックアップが行われ、ディスク領域の量が削減されます。ファイルが変更されていない場合、ファイルはファイルの古いインスタンスにハードリンクされ、変更されたファイルは新たにコピーされます。
また、サーバー上の構成ファイルrm file.cfg && ln ~/tmp/file.cfg file.cfg
をスワップアウトするためにも使用しています。〜/ tmp/*ファイルは安全に削除できます。
すでに存在するいくつかの良い議論に追加するには...
(inode, name)
ペアの固定形式リスト)は、ハードリンクを使用することでファイルシステムに余分なコストがかからないことを意味します(ハードリンクを禁止してサイクルを禁止する限り、ディレクトリ(.
と..
以外(これは他の人にとってLISPのように感じ始めますか?)))無料で入手できます。
私はおそらくハードリンクの落とし穴シナリオをカバーする必要があります。ハードリンクは、名前が異なるか、場所が異なる同じファイルです元のリンクファイルが存在する限り。ファイルを「元の」ファイルと考えるのも正しくありません。両方ともそれ自体がディレクトリエントリであり、両方(またはそれ以上)はすべて同等のピアです。長期間有効なファイルの場合、これは幸運かもしれませんが、ペアの1つが削除されてから作成された場合、同じ名前と内容であっても、ファイルは分離します。
_/foo/myfile
_へのハードリンク_/repo/myfile
_リンクを作成したとします。どちらも同じファイルデータへのポインタです。 1つを変更し、他の変更。しかし、_/repo
_がたまたまGitリポジトリを保持しているとします。 myfile
を含まないブランチをチェックアウトすると、_/repo/myfile
_が削除されます。この時点で、_/foo/myfile
_は、ペアの他の1つがリンク解除された時点での_/repo/myfile
_の単純なコピーになります。ファイルレパートリーが変更するブランチを切り替えても気付かないことは簡単ですが、元のブランチをチェックアウトすると、Gitによってnewファイル_/repo/myfile
_が作成されます。注意しないと、ファイル間のハードリンク関係にファイル名がわからないため、2つのファイルの内容が異なるのはなぜでしょうか。反対に、ソフトリンクは、この削除と作成のサイクルを通じて存続します。
一方、ハードリンクを使用するソフトウェアはこれを強く認識しており、Gitはその典型的な例です。 Gitは、ファイルをコピーする代わりにデフォルトでハードリンクを使用するため、ほぼ無料で同じファイルシステムにリポジトリを複製します。 Gitの場合、ハードリンクは完璧なユースケースです。オブジェクトとパックファイルは変更されないため、リポジトリの1つのクローンがもう1つを変更することはなく(Gitは変更可能なファイルをハードリンクしないことを認識しています)、任意のクローンを変更できます。注意なしに削除:「オリジナル」であるものを追跡する必要はありません実際にファイルを含みます:ハードリンクは同等のパートナーであり、完全なファイルを「含みます」。ソフトリンクはここでは機能しません。
ハードリンクのもう1つの利点は、ファイルの内容へのアクセスを中断せずにリンクを移動できることです。ソフトリンクでは、元のファイルを移動すると、すべてのソフトリンクがぶら下がっています。
結論としては、多くの使用例ではどちらのリンクタイプも同等に機能しますが、どちらか一方のタイプが有利です。ここで多くの回答で述べられている効率は、最新のマシンやファイルシステムではほとんど問題にならないでしょう。ただし、ちっぽけな組み込みコントローラーのフラッシュチップでファイルシステムを清掃する場合を除きます。 機能の違いの方が重要であり、通常、エンジニアリングの制約と最終的な選択を決定します。
また、ファイルを削除するライブラリ呼び出しは、理由のためにunlink()
と呼ばれていることも指摘しておく必要があります。すべてのディレクトリエントリは、そのiノードへの最初の単一のハードリンクにすぎません。