Les liens durs de répertoire cassent le système de fichiers de plusieurs façons
Ils vous permettent de créer des boucles
Un lien dur vers un répertoire peut être lié à un parent de lui-même, ce qui crée une boucle du système de fichiers. Par exemple, ces commandes peuvent créer une boucle avec le lien retour l
:
mkdir -p /tmp/a/b
cd /tmp/a/b
ln -d /tmp/a l
Un système de fichiers avec une boucle de répertoire a une profondeur infinie :
cd /tmp/a/b/l/b/l/b/l/b/l/b
Éviter une boucle infinie lors de la traversée d'une telle structure de répertoire est quelque peu difficile (bien que POSIX exige par exemple que find
pour éviter cela).
Un système de fichiers avec ce type de lien dur n'est plus un arbre, car un arbre ne doit pas, par définition, contenir de boucle.
Ils brisent l'univocité des répertoires parents.
Avec une boucle de système de fichiers, plusieurs répertoires parents existent :
cd /tmp/a/b
cd /tmp/a/b/l/b
Dans le premier cas, /tmp/a
est le répertoire parent de /tmp/a/b
.
Dans le second cas, /tmp/a/b/l
est le répertoire parent de /tmp/a/b/l/b
qui est identique à /tmp/a/b
.
Il a donc deux répertoires parents.
Ils multiplient les dossiers
Les fichiers sont identifiés par des chemins, après résolution des liens symboliques. Ainsi,
/tmp/a/b/foo.txt
/tmp/a/b/l/b/foo.txt
sont des fichiers différents.
Il existe une infinité de chemins supplémentaires pour le fichier. Ils sont identiques en termes de numéro d'inode, bien sûr. Mais si vous ne vous attendez pas explicitement à des boucles, il n'y a aucune raison de vérifier cela.
Un lien dur de répertoire peut également pointer vers un répertoire enfant, ou un répertoire qui n'est ni enfant ni parent d'aucune profondeur. Dans ce cas, un fichier qui est un enfant du lien serait répliqué en deux fichiers, identifiés par deux chemins.
Votre exemple
$ ln /Some/Directory /home/nischay/Hard-Directory
$ echo foo > /home/nischay/Hard-Directory/foobar.txt
$ diff -s /Some/Directory/foobar.txt /home/nischay/Hard-Directory/foobar.txt
Files /Some/Directory/foobar.txt and /home/nischay/Hard-Directory/foobar.txt are identical
$ echo bar >> /Some/Directory/foobar.txt
$ diff -s /Some/Directory/foobar.txt /home/nischay/Hard-Directory/foobar.txt
Files /Some/Directory/foobar.txt and /home/nischay/Hard-Directory/foobar.txt are identical
$ cat /Some/Directory/foobar.txt
foo
bar
Comment les liens mous vers les annuaires peuvent-ils alors fonctionner ?
Un chemin d'accès qui peut contenir des liens souples et même des boucles de répertoire souples est souvent utilisé uniquement pour identifier et ouvrir un fichier. Il peut être utilisé comme un chemin normal et linéaire.
Mais il existe d'autres situations où les chemins sont utilisés pour comparer des fichiers. Dans ce cas, les liens symboliques dans le chemin peuvent être résolus d'abord, en le convertissant en un fichier minimal et d'une représentation acceptée par tous, créant une chemin canonique :
Cela est possible, car les liens souples peuvent tous être étendus à des chemins sans lien. Après avoir fait cela avec tous les liens mous d'un chemin, le chemin restant fait partie d'un arbre, où un chemin est toujours sans ambiguïté.
La commande readlink
peut résoudre un chemin vers son chemin canonique :
$ readlink -f /some/symlinked/path
Les liens logiciels sont différents de ceux utilisés par le système de fichiers.
Un lien logiciel ne peut pas causer tous les problèmes car il est différent des liens à l'intérieur du système de fichiers. Il peut être distingué des liens durs, et résolu en un chemin sans symlinks si nécessaire.
Dans un certain sens, l'ajout de liens symboliques ne modifie pas la structure de base du système de fichiers - il la conserve, mais ajoute une structure supplémentaire comme une couche d'application.
Von 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
[ ... ]