web-dev-qa-db-ja.com

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

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のみですか?

126
Nischay

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

ループを作成できます

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

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

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

しかし、パスを使用してファイルを比較する場合、他の状況もあります。この場合、パス内のシンボリックリンクを最初に解決し、minimalに変換し、標準パス

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

コマンド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
        [  ...  ]
154
Volker Siegel

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

シンボリックリンクは:

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

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

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

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

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

77
user133232

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

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

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

43
stackount

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

19
astex