Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
doc:systeme:ln [11/08/2024 18:16] agp91 [Les liens physiques (hardlink) > Créer un lien physique] : Correction de la note explicative du second champ retourné par la commande ls -l |
doc:systeme:ln [14/08/2024 17:38] (Version actuelle) agp91 [Les liens physiques (hardlink) ] : Corrections de code |
||
---|---|---|---|
Ligne 11: | Ligne 11: | ||
* Suivi : {{tag>à-compléter}}{{tag>à-tester}} | * Suivi : {{tag>à-compléter}}{{tag>à-tester}} | ||
* Création par [[user>smolski]] le 21/06/2010 | * Création par [[user>smolski]] le 21/06/2010 | ||
- | * Testé par [[user>agp91]] le 04/07/2024 | + | * Modifié par [[user>agp91]] le 11/08/2024 |
* Commentaires sur le forum : [[http://debian-facile.org/viewtopic.php?pid=113446|C'est ici]]((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) | * Commentaires sur le forum : [[http://debian-facile.org/viewtopic.php?pid=113446|C'est ici]]((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) | ||
Ligne 655: | Ligne 655: | ||
\\ | \\ | ||
L'identifiant d'un inode est unique, uniquement dans le système de fichier au quel il appartient.\\ | L'identifiant d'un inode est unique, uniquement dans le système de fichier au quel il appartient.\\ | ||
- | Puisqu'il ne peut être unique dans d'autres systèmes de fichier, un nom ne peut pas être lié à l'inode d'un fichier, situé dans un autre système de fichier.</note> | + | Puisque l'identifiant d'un inode n'est unique que dans son système de fichier (il peut exister dans un autre système de fichier), un nom ne peut donc être lié à l'inode d'un autre système de fichier.</note> |
Commençons par créer un fichier de départ vide, ''test2.txt'' : | Commençons par créer un fichier de départ vide, ''test2.txt'' : | ||
Ligne 676: | Ligne 676: | ||
<code user> | <code user> | ||
ln test2.txt lien2.txt | ln test2.txt lien2.txt | ||
- | ls -lv | + | ls -l |
</code><code> | </code><code> | ||
total 0 | total 0 | ||
Ligne 738: | Ligne 738: | ||
Toutes les modifications, __ajoutées ou retranchées__ dans chacun des fichiers agira de même dans l'autre. | Toutes les modifications, __ajoutées ou retranchées__ dans chacun des fichiers agira de même dans l'autre. | ||
- | ==== Occupation concrète sur le disque ==== | + | ==== Occupation sur le disque ==== |
- | À l'aide de la commande ''ls -li'', nous pouvons voir l'occupation disque générée par un lien //hardlink// en constatant les chiffres indiquant les index respectifs des inodes de chacun des fichiers liés : | + | À l'aide de la commande ''ls -li'', nous pouvons voir la taille des fichiers et comparer leurs inodes : |
<code user> | <code user> | ||
Ligne 750: | Ligne 750: | ||
</code> | </code> | ||
- | Ah ! Le même index d'inode pour les deux fichiers ! | + | Ah ! Le même d'inode pour les deux fichiers ! |
- | Cela implique qu'__il n'y a pas deux occupations différentes__ sur le disque mais une seule occupation vers laquelle __pointe les deux fichiers__ liés en même temps ! :-) | + | Cela implique qu'__il n'y a pas deux occupations différentes__ sur le disque.\\ |
+ | Ces deux fichiers sont deux noms différents liés physiquement au même inode.\\ | ||
+ | Ayant le même inode ils utilisent la même liste de bloc mémorisée par l'inode. | ||
//On va pas s'gêner avec pour les gonfler de données car cela ne doublera pas l'occupation physique du disque !// :-D | //On va pas s'gêner avec pour les gonfler de données car cela ne doublera pas l'occupation physique du disque !// :-D | ||
+ | |||
+ | Pourtant ce n'est pas ce qu'indique le total de la commande ''ls -l''.\\ | ||
+ | Ce total retourne que les deux fichiers (qui ne sont qu'un) occupent sur le disque 8 K octets.\\ | ||
+ | La commande ''ls -lh'' le montre : | ||
+ | |||
+ | <code user> | ||
+ | ls -lh | ||
+ | </code><code> | ||
+ | total 8,0 K | ||
+ | -rw-r--r-- 2 martin martin 32 déc 15 13:52 lien2.txt | ||
+ | -rw-r--r-- 2 martin martin 32 déc 15 13:52 test2.txt | ||
+ | </code> | ||
+ | |||
+ | Ces fichiers ont une taille de 32 octets chacun (c'est indiqué dans le 5em champ),\\ | ||
+ | Selon ''ls'', ils occuperaient chacun un bloc (de 4 K octets), qu'elle additionne.\\ | ||
+ | C'est ce que montre ''ls -lsh'' : | ||
+ | |||
+ | <code user> | ||
+ | ls -lsh | ||
+ | </code><code> | ||
+ | total 8,0 K | ||
+ | 4,0K -rw-r--r-- 2 martin martin 32 déc 15 13:52 lien2.txt | ||
+ | 4,0K -rw-r--r-- 2 martin martin 32 déc 15 13:52 test2.txt | ||
+ | </code> | ||
+ | |||
+ | Il en va de même avec la commande ''stat'' (d'écrite plus haut à la section [[#creer-un-lien-symbolique|Créer un lien symbolique]]), qui avec l'option ''-c'' permet de définir les informations retournées.\\ | ||
+ | Voici d'autres formats supportés : | ||
+ | |||
+ | * ''%b'' indique le nombre de bloc utilisé par un fichier. | ||
+ | * ''%B'' retourne la taille d'un bloc. | ||
+ | * Et ''%n'' retourne le nom du fichier. | ||
+ | |||
+ | <code user> | ||
+ | stat -c "%b (x%B) %n" * | ||
+ | </code><code> | ||
+ | 8 (x512) lien2.txt | ||
+ | 8 (x512) test2.txt | ||
+ | </code> | ||
+ | |||
+ | La commande ''stat'' utilise par défaut des blocs de 512 octets.\\ | ||
+ | 8x512 = 4096 (soit 4K octets), cela correspond aux tailles retournées par la commande ''ls''. | ||
+ | |||
+ | Mais cela est évidement erroné,\\ | ||
+ | Puisque ''lien2.txt'' et ''test2.txt'', sont des noms (chemins) différents, qui mènent au même fichier (inode) stocké dans le système de fichier (sur le disque). | ||
+ | |||
+ | <note tip> | ||
+ | Pour connaître la taille réelle occupée par des fichiers, la commande ''du'' doit être utilisée. | ||
+ | </note> | ||
+ | |||
+ | <code user> | ||
+ | du -h * | ||
+ | </code><code> | ||
+ | 4,0K lien2.txt | ||
+ | </code> | ||
+ | |||
+ | Puisque ''lien2.txt'' et ''test2.txt'' sont le même fichier, ''du'' n'en retourne qu'un.\\ | ||
+ | La taille total occupée est donc de 4 K octets, soit un bloc. | ||
+ | |||
+ | Il est remarquable qu'ici ne soit pas retourné le fichier original.\\ | ||
+ | ''Du'' a simplement retourné le premier lien physique rencontré.\\ | ||
+ | Cela met en évidence qu'il n'y a pas de différence entre le fichier original et le(s) fichier(s) qui lui est (sont) lié(s). | ||
+ | |||
+ | ==== Copies de fichier lié physiquement ==== | ||
+ | |||
+ | 8 K octets sera la taille totale obtenu si l'on copie ces deux fichiers liés : | ||
+ | |||
+ | <code user> | ||
+ | mkdir rep1 | ||
+ | cp -v *2.txt rep1 | ||
+ | </code><code> | ||
+ | 'lien2.txt' -> 'rep1/lien2.txt' | ||
+ | 'test2.txt' -> 'rep1/test2.txt' | ||
+ | </code> | ||
+ | |||
+ | **__Note__ :** L'option ''-c'' de la commande ''du'' demande le total des fichiers listés. | ||
+ | |||
+ | <code> | ||
+ | du -ch rep1/* | ||
+ | </code><code> | ||
+ | 4,0K rep1/lien2.txt | ||
+ | 4,0K rep1/test2.txt | ||
+ | 8,0K total | ||
+ | </code> | ||
+ | |||
+ | Ce coup ci, la commande ''du'' retourne deux fichiers de 4 K octets (1 bloc) chacun, soit un total de 8 K octets. | ||
+ | |||
+ | Le format ''%i'' de la commande ''stat'' retourne l'inode indexé d'un fichier.\\ | ||
+ | Et ''%h'' le nombre de lien physique que dispose un fichier. | ||
+ | |||
+ | <code user> | ||
+ | stat -c "%i %h %n" *.txt rep1/*.txt | ||
+ | </code><code> | ||
+ | 8667149 2 lien2.txt | ||
+ | 8667149 2 test2.txt | ||
+ | 8667652 1 rep1/lien2.txt | ||
+ | 8667653 1 rep1/test2.txt | ||
+ | </code> | ||
+ | |||
+ | Les inodes sont différents, il s’agit donc de deux fichiers différents.\\ | ||
+ | La commande ''cp'' à copier le fichier ''lien2.txt'' puis le fichier ''test2.txt'', sans maintenir les liens physiques. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | <note tip> | ||
+ | L'option ''-l'' de la commande ''cp'' permet de lier physiquement des fichiers au lieu de les copier.\\ | ||
+ | (A condition qu'ils soient <del>copiés</del> liés dans le même système de fichier.) | ||
+ | </note> | ||
+ | |||
+ | <code user> | ||
+ | rm -v rep1/* | ||
+ | </code><code> | ||
+ | 'rep1/lien2.txt' supprimé | ||
+ | 'rep1/test2.txt' supprimé | ||
+ | </code> | ||
+ | |||
+ | <code user> | ||
+ | cp -vl *2.txt rep1 | ||
+ | </code><code> | ||
+ | 'lien2.txt' -> 'rep1/lien2.txt' | ||
+ | 'test2.txt' -> 'rep1/test2.txt' | ||
+ | </code> | ||
+ | |||
+ | <code user> | ||
+ | stat -c "%i %h %n" * rep1/* | ||
+ | </code><code> | ||
+ | 8667149 4 lien2.txt | ||
+ | 8695636 2 rep1 | ||
+ | 8667149 4 test2.txt | ||
+ | 8667149 4 rep1/lien2.txt | ||
+ | 8667149 4 rep1/test2.txt | ||
+ | </code> | ||
+ | |||
+ | Les deux nouveaux fichiers ont les mêmes inodes que les originaux. Ce sont donc des fichiers liées.\\ | ||
+ | Le champs qui indique le nombre de lien physique (celui retourné par ''%h''), montre qu'il y a maintenant 4 fichiers liés (un seul fichier disposant de 4 noms). | ||
+ | |||
+ | **__Remarque__ :** Pour le répertoire ''rep1'', ce champs retourne 2 ! | ||
+ | |||
+ | ==== Répertoires et lien physique ==== | ||
+ | |||
+ | Le système ne permet pas de créer un lien physique pour un répertoire : | ||
+ | |||
+ | <code user> | ||
+ | ln rep1 rep2 | ||
+ | </code><code> | ||
+ | ln: rep1 : lien direct non permis pour un répertoire | ||
+ | </code> | ||
+ | |||
+ | Même //root// ne peut le faire : | ||
+ | |||
+ | <code root> | ||
+ | ln rep1 rep2 | ||
+ | </code><code> | ||
+ | ln: rep1 : lien direct non permis pour un répertoire | ||
+ | </code> | ||
+ | |||
+ | Pourtant, le système en crée deux à chaque nouveau répertoire : | ||
+ | |||
+ | * ''.'' lié physiquement au répertoire créé, | ||
+ | * Et ''..'' lié physiquement au répertoire parent. | ||
+ | |||
+ | **__Rappel__ :** Dans un système de fichier, un répertoire est un fichier qui contient tous les noms des fichiers (et répertoires) de ce répertoire. | ||
+ | |||
+ | Ces deux fichiers (''.'' et ''..'') commencent par un point, ce sont donc des fichiers cachés.\\ | ||
+ | Ils sont visible avec l'option ''-a'' de la commande ''ls'' (l'option ''-R'' demande un listing récursif) : | ||
+ | |||
+ | <code user> | ||
+ | ls -Ra | ||
+ | </code><code> | ||
+ | .: | ||
+ | . .. lien2.txt rep1 test2.txt | ||
+ | |||
+ | ./rep1: | ||
+ | . .. lien2.txt test2.txt | ||
+ | </code> | ||
+ | |||
+ | .. Ou s'ils sont directement nommés : | ||
+ | |||
+ | <code user> | ||
+ | stat -c "%i %h %n" rep1 rep1/. rep1/.. . ~/test_lien | ||
+ | </code><code> | ||
+ | 8695636 2 rep1 | ||
+ | 8695636 2 rep1/. | ||
+ | 8695247 3 rep1/.. | ||
+ | 8695247 3 . | ||
+ | 8695247 3 /home/martin/test_lien | ||
+ | </code> | ||
+ | |||
+ | Ci-dessus est visible que : | ||
+ | |||
+ | * ''rep1'' et ''rep1/.'' ont le même inode. | ||
+ | * ''.'', ''test_lien'' et ''rep1/..'' ont le même inode. | ||
+ | |||
+ | Ainsi un répertoire est lié physiquement 2 fois : Par son nom et par le fichier ''.'' qu'il contient.\\ | ||
+ | Plus un (+1) lien physique par répertoire fils (sous-répertoire) qu'il contient. | ||
+ | |||
+ | Par exemple, s'il est ajouté 4 autres répertoires au répertoire ''test_lien'' (cela lui fera cinq sous-répertoires), il sera alors lié 7 fois : | ||
+ | |||
+ | <code user> | ||
+ | mkdir -v rep{2..5} | ||
+ | </code><code> | ||
+ | mkdir: création du répertoire 'rep2' | ||
+ | mkdir: création du répertoire 'rep3' | ||
+ | mkdir: création du répertoire 'rep4' | ||
+ | mkdir: création du répertoire 'rep5' | ||
+ | </code> | ||
+ | |||
+ | <code user> | ||
+ | stat -c "%i %h %n" ~/test_lien . rep*/.. | ||
+ | </code><code> | ||
+ | 8695247 7 /home/martin/test_lien | ||
+ | 8695247 7 . | ||
+ | 8695247 7 rep1/.. | ||
+ | 8695247 7 rep2/.. | ||
+ | 8695247 7 rep3/.. | ||
+ | 8695247 7 rep4/.. | ||
+ | 8695247 7 rep5/.. | ||
+ | </code> | ||
+ | |||
+ | ---- | ||
+ | |||
+ | <code user> | ||
+ | rmdir rep{2..5} | ||
+ | </code> | ||
==== Suppression des fichiers ==== | ==== Suppression des fichiers ==== | ||
- | Suppression du fichier cible ''test2.txt'' : | + | Supprimer des fichiers liés n’altère en rien ceux qui restent. |
+ | |||
+ | **__Note__ :** La commande ''rm -r //<chemin_répertoire>//'' permet de supprimer un répertoire non vide (et tout ce qu'il contient, sous-répertoires compris) | ||
+ | |||
+ | <code user> | ||
+ | rm -rv rep1 | ||
+ | </code><code> | ||
+ | 'rep1/lien2.txt' supprimé | ||
+ | 'rep1/test2.txt' supprimé | ||
+ | répertoire 'rep1' supprimé | ||
+ | </code> | ||
+ | |||
+ | <code user> | ||
+ | ls -li | ||
+ | </code><code> | ||
+ | total 8 | ||
+ | 8667149 -rw-r--r-- 2 martin martin 32 déc 15 13:52 lien2.txt | ||
+ | 8667149 -rw-r--r-- 2 martin martin 32 déc 15 13:52 test2.txt | ||
+ | </code> | ||
+ | |||
+ | Même supprimer le fichier original (qui en réalité ne peut plus être distingué), ne supprime pas les autres fichiers qui lui ont été liés : | ||
<code user> | <code user> | ||
rm test2.txt | rm test2.txt | ||
- | ls -l | + | ls -li |
</code><code> | </code><code> | ||
- | total 4 | + | 8667149 -rw-r--r-- 1 martin martin 32 déc 15 13:52 lien2.txt |
- | -rw-r--r-- 1 martin martin 32 déc 15 13:52 lien2.txt | + | |
</code> | </code> | ||
+ | |||
Comme dit le captnfab dans sa relecture : \\ | Comme dit le captnfab dans sa relecture : \\ | ||
- | Il est à remarquer que le chiffre ''2'' est passé à ''1'' car il n'y a plus de second fichier lié. | + | Il est à remarquer que le chiffre indiquant le nombre de fichier lié est passé à ''1'' car il n'y a plus d'autre fichier lié.\\ |
+ | (Il ne reste plus qu'un seul nom lié à l'inode du fichier). | ||
- | <note tip>Chacun des fichiers liés par un lien physique survit nominalement et physiquement à l'effacement de l'autre.</note> | + | Pour supprimer définitivement des fichiers liés, tous doivent être supprimés. |
- | Pour supprimer définitivement les deux fichiers et leurs contenus, nous devons les effacer tous deux. | ||
<code user> | <code user> | ||
- | rm *2.txt | + | rm lien2.txt |
ls -l | ls -l | ||
</code><code> | </code><code> | ||
total 0 | total 0 | ||
</code> | </code> | ||
- | |||
- | //Voilà pour la commande //''ln''// dans tous ses états !// | ||
- | |||
- | //Merci au //**captnfab**// pour sa bienveillante et rigolote attention !// :-D | ||
===== Conclusion ===== | ===== Conclusion ===== | ||
Ligne 791: | Ligne 1033: | ||
Autre point très intéressant, créer des liens, au lieu de copier les fichiers, assure que toute modification dans un fichier se retrouvera bien dans les « copies » dispersées un peu partout. | Autre point très intéressant, créer des liens, au lieu de copier les fichiers, assure que toute modification dans un fichier se retrouvera bien dans les « copies » dispersées un peu partout. | ||
+ | |||
+ | //Voilà pour la commande //''ln''// dans tous ses états !// | ||
+ | |||
+ | //Merci au //**captnfab**// pour sa bienveillante et rigolote attention !// :-D | ||