ディレクトリにハードリンクが許可されないのはなぜですか?


129

Ubuntu 12.04を使用しています。ディレクトリのハードリンクを作成しようとすると、失敗します。ファイルシステム境界内のファイルのハードリンクを作成できます。ファイルシステムを超えてファイルのハードリンクを作成できない理由はわかっています。

私はこれらのコマンドを試しました:

$ ln /Some/Direcoty /home/nischay/Hard-Directory
hard link not allowed for directory
$ sudo ln /Some/Direcoty /home/nischay/Hard-Directory
[sudo] password for nischay: 
hard link not allowed for directory

この理由を知りたいだけです。すべてのGNU / LinuxディストリビューションとUnixフレーバー(BSD、Solaris、HP-UX、IBM AIX)で同じですか、それともUbuntuまたはLinuxのみですか?



2
試してみてln -F <src> <dst>、うまくいくかもしれません。確かに、古いバージョンのUnixのスーパーユーザーで使用されていました。UCBかSystem Vかを覚えている人はいますか?はい、悪いことが起こる可能性がありますが、通常は起こりません。私が思い出すようにrmdir、ハードリンクを過ぎて削除を続けないことを知っていました。ただし、ユーザーは混乱して、誤って削除する可能性があります。
スティーブピッチャーズ14

@StevePitchers rmdirハードリンクを特別な方法で処理するにはどうすればよいですか?ハードリンクは単なる通常のリンクですが、追加のリンクです。追加の録音を行わずに異常な追加リンクが存在するかどうかを確認することさえ容易ではありません。
フォルカーシーゲル

1
各ノードは、それを指すハードリンクの数を格納します。コンテンツは、リンクが残っていない場合にのみ解放されます。そのrmdirため、ディレクトリに他の場所からのリンクがあるかどうかを確認できます。rm -r"permission denied"のようなエラーがあっても正しく動作するように、再帰的な削除は慎重にコーディングする必要があります。ところで、UCB = BSD、doh!
スティーブピッチャーズ

2
私はln -Fディレクトリを作成し、機能させています。ただし、ファイルシステムが破損する恐れがあるため、後でディレクトリを削除しないでください。
エドワードフォーク

回答:


159

ディレクトリのハードリンクは、複数の方法でファイルシステムを破壊します

ループを作成できます

ディレクトリへのハードリンクは、それ自体の親にリンクでき、ファイルシステムループを作成します。たとえば、これらのコマンドはバックリンクでループを作成できますl

mkdir -p /tmp/a/b
cd /tmp/a/b
ln -d /tmp/a l

ディレクトリループのあるファイルシステムの深さは無限です:

cd /tmp/a/b/l/b/l/b/l/b/l/b

このようなディレクトリ構造を走査するときに無限ループを回避することはやや困難です(たとえば、POSIXではfindこれを回避する必要があります)。

この種のハードリンクを含むファイルシステムは、ツリーではありません。ツリーは、定義上、ループを含んではならないためです。

親ディレクトリの曖昧さを解消します

ファイルシステムループでは、複数の親ディレクトリが存在します。

cd /tmp/a/b
cd /tmp/a/b/l/b

最初の場合、/tmp/aはの親ディレクトリです/tmp/a/b
2番目の場合、/tmp/a/b/lはの親ディレクトリです/tmp/a/b/l/b。これはと同じ/tmp/a/bです。
そのため、2つの親ディレクトリがあります。

ファイルを増やす

ファイルは、シンボリックリンクを解決した後、パスによって識別されます。そう

/tmp/a/b/foo.txt
/tmp/a/b/l/b/foo.txt

異なるファイルです。
さらに多くのファイルのパスがあります。もちろん、iノード数の点では同じです。ただし、ループを明示的に予期していない場合は、それを確認する理由はありません。

ディレクトリハードリンクは、子ディレクトリ、または任意の深さの子でも親でもないディレクトリを指すこともできます。この場合、リンクの子であるファイルは、2つのパスで識別される2つのファイルに複製されます。

あなたの例

$ ln /Some/Direcoty /home/nischay/Hard-Directory
$ echo foo > /home/nischay/Hard-Directory/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ echo bar >> /Some/Direcoty/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ cat /Some/Direcoty/foobar.txt
foo
bar

ディレクトリへのソフトリンクはどのように機能しますか?

ソフトリンクやソフトリンクされたディレクトリループを含む可能性のあるパスは、ファイルを識別して開くためだけによく使用されます。通常の線形パスとして使用できます。

しかし、パスを使用してファイルを比較する場合、他の状況もあります。この場合、パス内のシンボリックリンクを最初に解決し、それを最小値に変換し、一般的なパスを作成する表現に一般的に同意することができます

ソフトリンクはすべて、リンクなしのパスに展開できるため、これは可能です。パス内のすべてのソフトリンクでこれを実行すると、残りのパスはツリーの一部になり、パスは常に明確になります。

このコマンドreadlinkは、パスを正規のパスに解決できます。

$ readlink -f /some/symlinked/path

ソフトリンクはファイルシステムが使用するものとは異なります

ソフトリンクはファイルシステム内のリンクとは異なるため、すべての問題を引き起こすことはできません。ハードリンクと区別でき、必要に応じてシンボリックリンクのないパスに解決できます。
ある意味では、シンボリックリンクを追加しても基本的なファイルシステム構造は変更されません-維持されますが、アプリケーション層のような構造が追加されます。


からman readlink

 NAME
        readlink - print resolved symbolic links or canonical
        file names

 SYNOPSIS
        readlink [OPTION]... FILE...

 DESCRIPTION
        Print value of a symbolic link or canonical file name

        -f, --canonicalize
               canonicalize by  following  every  symlink  in
               every component of the given name recursively;
               all but the last component must exist
        [  ...  ]

1
ソフトリンクではこれができないのはなぜですか?
タナイ

1
@Tanay正しい、拡張機能がソフトリンクを使用した同様のケースと比較するのに役立ちます。私が試してみます。
フォルカージーゲル

これは、ディレクトリだけにどのように関係していますか?私の理解では、これらの問題はハードリンクされたファイルの問題でもあります。さらに、ハードリンクは、特定のディレクトリのアクセス権を変更して、他のユーザーを親チェーン内でも許可せずに、他のユーザーを許可する簡単な方法だと考えています。サウンドは非常にあなたがグループを追加/変更する機能を持っていない場合は...便利
inetknght

素晴らしい答えですが、それでは... AppleはTime Machineのこれらの問題をどのように解決しましたか?
ダミアン

とても面白いですね!しかし、私は問題が何であるかについて何も知りません-ヒントを教えてもらえますか?
フォルカーシーゲル

77

「とにかく、通常はハードリンクを使用しないでください」は広範です。ハードリンクとシンボリックリンクの違いを理解し、必要に応じてそれぞれを使用する必要があります。それぞれに長所と短所があります:

シンボリックリンクは:

  • ディレクトリを指す
  • 存在しないオブジェクトを指す
  • 同じファイルシステムの外部のファイルとディレクトリを指す

ハードリンクは次のことができます。

  • 参照するファイルが削除されないようにします

ハードリンクは、「コピーオンライト」アプリケーションの実行に特に役立ちます。2つのバージョン間で変更されるファイルにスペースのみを使用しながら、ディレクトリ構造のバックアップコピーを保持できます。

cp -alこの点でこのコマンドは特に便利です。ディレクトリ構造の完全なコピーを作成します。すべてのファイルは、元のファイルへのハードリンクで表されます。その後、構造内のファイルの更新に進むことができ、更新するファイルのみが追加のスペースを占有します。これは、複数世代のバックアップを維持する場合に特に役立ちます。


41
最後の段落に関して、「コピーされた」ハードリンクファイルを編集すると、元のファイルも変更されます-unix.stackexchange.com/questions/70531/…を
marcin

32
このハードリンクの説明は、かなり誤解を招くものです。基本的に、ハードリンクが「参照されているファイルが削除されないようにする」のは事実ですが、それはハードリンクの副作用にすぎません。1つのディレクトリにハードリンクを作成し、「元の」ファイルを変更し、ハードリンクが何らかの形で古いコンテンツを指すことを期待できることは確かに真実ではありません。実際、ハードリンクの基本的な真実は、それがまったくリンクではないという事実です。少なくとも、ファイルを指す名前である元の「ファイル」ほどではありません。ハードリンクは、同じファイルを指す別の名前です。
マティ

7
バックアップのアイデアは優れており、実際に多く使用していますが、ファイルを変更するとバックアップも変更されることをユーザーに警告する必要があると思います。
マーク

3
ヘック、シンボリックリンクは何も指す必要はありません。ln -s "Don't use this directory" README合法です。実際、考えてみると、ディレクトリはリレーショナルデータベースとして使用でき、実際のファイルはまったく含まれていません。
エドワードフォーク

5
-1これは質問に答えず、いくつかの情報は明らかに間違っています。
wjandrea

43

参考までに、mountを使用してディレクトリのハードリンクと同じことを実現できます。

mount -t bind /var/www /home/user/workspace/www

ほとんどのツールとプログラムはバインディングを認識しないため、これは非常に危険です。上記の例のようなことをした後、に進みましたrm -rf /home/user。幸いなことに、関連するものはありませんでした/var/www


6
使用しましたmount --bind <src> <dest>src;)を
拭か

1
私が得ます:mount: unknown filesystem type 'bind'
Wizek

4
Busyboxで、それmount -o bind src dest
Mat M

@MatM Debianと同じ
hanshenrik

2
読み取り専用にマウントする必要がある場合は、マウントポイントにアクセス許可を設定して、rm -rf問題を回避できます。superuser.com/questions/320415/...
zanerock

19

ディレクトリのハードリンクが許可されない理由は少し技術的です。基本的に、ファイルシステム構造を破壊します。とにかくハードリンクは一般的に使用しないでください。シンボリックリンクを使用すると、問題を引き起こすことなく同じ機能のほとんどを使用できます(例:)ln -s target link


17
ハードリンクには良い使用例があります。一般にそれらを使用すべきではないと言うのは、少し広すぎます。
サンダーステファン

4
OPの質問(および私のもの)に実際に答えるリンクを提供する場合は+2、意見を出す場合は-1(「とにかくハードリンクは一般的に使用しないでください」-それをサポートするリンクがあれば大丈夫です)。とにかく+2を与えることができないので、どちらが良かった。; D
msb

3
「ファイルシステム構造を壊す」リンクは機能しません。
チャーリーパーカー14年

5
回答内のリンクの内容を要約し、参照としてリンクを保持してください。これは、リンクの腐敗を防ぐためのStack Exchangeの良い習慣です。ありがとう。
Oxwivi

3
よくできました@CharlieParker; 最高の意図しない(?)すべての回の皮肉なコメント:)
エリランマルカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.