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のみですか?
ディレクトリへのハードリンクは、それ自体の親にリンクでき、ファイルシステムループを作成します。たとえば、これらのコマンドは、バックリンク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
[ ... ]
「とにかく、通常はハードリンクを使用しないでください」は広範です。ハードリンクとシンボリックリンクの違いを理解し、必要に応じてそれぞれを使用する必要があります。それぞれに長所と短所があります:
シンボリックリンクは:
ハードリンクは次のことができます。
ハードリンクは、「コピーオンライト」アプリケーションの実行に特に役立ちます。 2つのバージョン間で変更されるファイル用のスペースのみを使用しながら、ディレクトリ構造のバックアップコピーを保持できます。
コマンドcp -al
は、この点で特に役立ちます。ディレクトリ構造の完全なコピーを作成します。すべてのファイルは、元のファイルへのハードリンクで表されます。その後、構造内のファイルの更新に進むことができ、更新するファイルのみが追加のスペースを占有します。これは、複数世代のバックアップを維持する場合に特に便利です。
参考までに、mountを使用してディレクトリのハードリンクと同じことを実現できます。
mount -t bind /var/www /home/user/workspace/www
ほとんどのツールとプログラムはバインディングを認識しないであるため、これは非常に危険です。上記の例のようなことを一度して、rm -rf /home/user
に進みました。幸いなことに、/var/www
に関連するものはありませんでした。
ディレクトリのハードリンクが許可されない理由は少し技術的です。基本的に、 ファイルシステム構造を壊します 。通常、ハードリンクは使用しないでください。シンボリックリンクを使用すると、ほとんど同じ機能を問題なく使用できます(例:ln -s target link
)。