====== ln ====== * Objet: commande ln * Niveau requis :{{tag>débutant avisé}} * Commentaires : // Permet de créer des liens physiques ou symboliques // * Débutant, à savoir : [[:doc:systeme:commandes:le_debianiste_qui_papillonne|Utiliser GNU/Linux en ligne de commande, tout commence là !]] :-) * [[:doc:programmation:shell:chevrons | La commande chevron ">"]] * [[:doc:systeme:ls | La commande ls]] * [[:doc:systeme:rm | La commande rm]] * [[:doc:systeme:droits-unix | Les droits]] * [[:doc:editeurs:nano | La commande d'édition nano]] * Suivi : {{tag>à-compléter}}{{tag>à-tester}} * Création par [[user>smolski]] le 21/06/2010 * 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 !)) =====Introduction===== La commande ''ln'' établit un lien symbolique ou un lien physique entre 2 fichiers. Les modifications opérées //sur/dans// l'un sont visibles immédiatement depuis l'un ou l'autre des fichiers liés. ===== Synopsis ===== ln [option] == Lien symbolique : == ln -s ln -s == Lien physique : == ln **ATTENTION :** Un lien physique à la particularité de devoir se situer __sur le même système de fichier__ que sa cible ! ===== Description ===== On distingue 2 sortes de lien : les liens durs et les liens symboliques. == Les liens symboliques (symlink) == Un lien symbolique est constitué d'un réel fichier de petite taille ; il contient le nom (chemin) du fichier auquel il correspond. Par conséquent, la suppression du fichier d'origine, c'est-à-dire la cible du lien, rendra le lien symbolique inutilisable puisqu'il ne correspondra plus à un fichier valide ; le lien sera alors brisé. == Les liens physiques ou durs (hardlink) == Un lien dur associe deux ou plusieurs fichiers à un même espace sur le disque. Ainsi un fichier peut disposer réellement de plusieurs noms (chemins). La suppression d'un fichier lié physiquement n'affectera pas les autres fichiers qui lui sont liés. **Nota :** \\ Les systèmes de fichier msdos/fat/vfat et exfat ne prennent pas en charge ni les liens symboliques, ni les liens physiques.\\ ([[https://debian-facile.org/viewtopic.php?pid=417068#p417068|Démonstration dans le forum]]) ===== Préparatifs ===== Afin de bien comprendre les principes que nous avons décrits ci-haut, nous allons illustrer tout cela à l'aide de quelques exemples simples. Dans ''/home/votre_user/'', créez un répertoire nommé ''test_lien'' avec [[:doc:systeme:mkdir|mkdir]] et s'y positionner avec [[:doc:programmation:shell:cd | cd]] : cd mkdir test_lien cd test_lien Créer dans ce répertoire un fichiers vide, ''test1.txt'', avec [[:doc:systeme:touch|touch]], puis ajoutez-y le texte //Bonjour toto// avec la commande [[:doc:systeme:echo|echo]]. touch test1.txt echo Bonjour Jojo > test1.txt On vérifie avec la commande [[:doc:systeme:cat|cat]] que notre texte est bien écrit dans le fichier test1.txt : cat test1.txt Bonjour Jojo ==== Théorie simplifiée ==== Pour enregistrée un fichier sur un disque (dans une partition formatée avec un système de fichier), le disque et le système de fichier, découpent l'espace alloué en très petites unités nommée **bloc**. Actuellement, sur un disque, la taille d'un bloc est le plus souvent de 4 K octets (4096 octets) ou de 512 octets (ancienne taille). Un bloc est la plus petite unité qui peut être lue ou écrite.\\ Par exemple pour un système de fichier dont les blocs sont déterminés à 512 octets : * Un fichier d'1 octet (d'un seul caractère) occupera un bloc complet. Sa taille sur le disque sera donc de 512 octets. * Un fichier de 513 octets (513 caractères) occupera deux blocs, sa taille sera donc 1024 octets (1 K octets). * Deux fichiers différents, d'un octet chacun, occupera chacun un bloc. Soit (pour les deux fichiers) un total de 1024 octets. La liste des blocs qu'utilise un fichier est mémorisée par son **inode**((Un **inode** (Index Node, nœud d'index, en français) est une structure de méta-données utilisée par un système de fichier de style Unix, pour identifier, décrire et accéder à un fichier.\\ Identifié par un identifiant unique (dans le système de fichier au quel il appartient), l'inode mémorise les informations inhérentes à un fichier. Par exemples : Son type, ses permissions, son propriétaire, son groupe, sa date de création, celle de modification, sa taille, la liste des blocs qu'il occupe, le nombre de nom lié, etc. Voir : [[https://fr.wikipedia.org/wiki/N%C5%93ud_d%27index|(fr) Noeud d'index (wikipedia.org)]])). Quand un fichier est créé, un **inode** lui est attribué. Il identifie de façon unique ce fichier dans son système de fichier.\\ Le nom du fichier est alors rattaché (lié physiquement) à cet inode. Il y a trois principaux types de bloc : * Les **blocs physiques**, qui sont définis par le matériel (le disque). *Les **blocs logiques**, qui sont aussi définis par le matériel. Ils permettent la rétrocompatibilité avec les systèmes qui ne supportent pas l'augmentation de la taille des blocs physiques, apportée par l'évolution du matériel. * Et les **blocs des systèmes de fichier**, qui sont définis par le système de fichier (lors du formatage). **__Notes__ :** Une couche d’abstraction logiciel, tel que LVM (gestion de volume logique) ou LUKS (chiffrement des partitions ou de volumes logiques), peut modifier la taille des blocs logiques. Ce tuto est réaliser dans un système de fichier ''ext4'', utilisant des blocs de 4096 octets.\\ Un fichier (s'il n'est pas vide), occupera donc sur le disque, au minimum, 4096 octets (4 K octets). ===== Les liens symboliques (symlink) : ===== Situation de départ : ls -l total 4 -rw-r--r-- 1 martin martin 13 déc 14 22:02 test1.txt ==== Créer un lien symbolique ==== On crée le lien symbolique : ln -s test1.txt lien1 Ce qui nous fait maintenant : ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt -rw-r--r-- 1 martin martin 13 déc 14 22:02 test1.txt Attardons-nous un peu sur la ligne : ''**l**rwxrwxrwx 1 martin martin **9** déc 14 22:05 lien1 **-> test1.txt**'' - Dans le 1er champ (''lrwxrwxrwx''), la première lettre : **''l''**, indique que ce fichier est un lien symbolique. - Dans le 5em champ, le chiffre **''9''**, indique la taille en octet du fichier (elle ne doit pas être confondue avec la taille d'occupation sur le disque). - **''-> test1.txt''** indique le fichier que désigne le lien symbolique. Précisons aussi que : * La taille d'un //fichier d'un lien symbolique// ne correspond pas à la taille de son fichier cible. * Les modifications apportées au contenu d'un fichier (cible) désigné par un lien symbolique seront portées uniquement dans le fichier cible. * La destruction totale d'un lien symbolique ne détruit rien dans le fichier cible. ---- Avant de poursuivre dans l'usage des liens symboliques,\\ Sont montrées, ci-dessous, quelques commandes qui ont attrait au liens symboliques. Il a déjà été vu l'option ''-l'' de la commande ''ls''.\\ Combinée avec l'option ''-L'', elle permet de retourner les informations de la cible plutôt que celles du lien : ls -Ll total 4 -rw-r--r-- 1 martin martin 13 déc 14 22:02 lien1 -rw-r--r-- 1 martin martin 13 déc 14 22:02 test1.txt L'option ''-F'' de la commande ''ls'', ajoute un ''@'' (arobase) à la fin de chaque lien symbolique listé, permettant ainsi de les distinguer. ls -F lien1@ test1.txt ---- La commande **''stat''**((La commande **stat** permet de retourner des informations sur un fichier ou un système de fichier. Dans l'écriture de script, il est conseillé d'utiliser ''stat'' au lieu de ''ls''. Car ''stat'' permet de spécifier les informations retournées. Contrairement à ''ls'', dont les champs retournés varient selon le type de fichier étudié et peuvent différer d'un système à l'autre. [[https://fr.manpages.org/stat|manuel (fr) stat (1) : Afficher l'état d'un fichier ou d'un système de fichiers (manpage.org)]] - ''man stat'')) qui permet de retourner des détails sur des fichiers.\\ (En permettant de choisir les informations retournées, la commande ''stat'' est plus souple que la commande ''ls''.)\\ Avec l'option ''-c'' et le format ''%N'', retourne le nom du fichier et s'il s’agit de lien symbolique, celui de sa cible : **__Note__ :** Dans un contexte de chemin, le caractère ''*'' est un caractère générique qui signifie n'importe quelle chaîne de caractère. stat -c%N * lien1 -> test1.txt test1.txt ---- La commande **''readlink''**((La commande **readlink** affiche le nom du fichier ou du répertoire que désigne un lien symbolique. Sans option est retourné le chemin (le nom) tel qu'il a été fourni lors de la création du lien. Différentes options permettent d'en retourner le chemin absolu (canonique). [[https://manpages.debian.org/unstable/manpages-fr/readlink.1.fr.html|manuel (fr) readlink (1) : Afficher la valeur d'un lien symbolique... (debian.org)]] - ''man readlink'')) retourne la cible mémorisée par un lien symbolique : readlink lien1 test1.txt ---- La commande ''**file**''((La commande **file** retourne le type d'un fichier. Voir : [[https://fr.wikipedia.org/wiki/File_(Unix)|(fr) file (UNIX) (wikipedia.org)]] - [[https://manpages.debian.org/unstable/manpages-fr/file.1.fr.html|manuel (fr) file (1) : Déterminer le type d'un fichier (debian.org)]] - ''man file'' )) retourne le type de fichier étudié, s'il s'agit d'un lien symbolique, sa cible est aussi indiquée : file lien1 lien1: symbolic link to test1.txt ==== Modification du contenu ==== echo Comment vas-tu ? >> lien1 cat lien1 Bonjour toto Comment vas-tu ? cat test1.txt Bonjour toto Comment vas-tu ? ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt -rw-r--r-- 1 martin martin 30 déc 14 22:08 test1.txt Nous pouvons voir que seul le fichier cible '''test1.txt'' s'est trouvé modifié, passant de **13** à **30** octets d'occupation ! Modifier directement le fichier cible donnera le même résultat : - Aucune modification pour le fichier du lien symbolique - Effectif pour le fichier cible ==== Occupation sur le disque ==== À l'aide de la commande ''ls -li'', nous pouvons voir la taille des fichiers et comparer leurs inodes (l'option ''-i'' demande l'affichage de l'identifiant d'un inode) : ls -li total 4 8667148 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt 8667139 -rw-r--r-- 1 martin martin 30 déc 14 22:08 test1.txt Le premier champ indique que chacun des fichiers ont un inode différent.\\ Cela implique qu'__il y a bien deux occupations différentes__ sur le disque (2 fichiers différents), avec une occupation qui restera toujours fixe et minimale pour le fichier du lien symbolique. :-) L'option ''-s'' de la commande ''ls'' indique la taille occupée par le(s) bloc(s) utilisé(s) par un fichier.\\ L'option ''-h'' permet de présenter les tailles avec l'unité la plus appropriée (Ko, Mo, Go, etc). ls -lsh total 4,0K 0 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt 4,0K -rw-r--r-- 1 martin martin 30 déc 14 22:08 test1.txt Le fichier ''test1.txt'' de 30 octets (28 caractères imprimables + 2 caractères de saut de ligne) occupe un bloc entier. Il a donc, ici, une taille de 4 K octets.\\ Le fichier du lien symbolique ''lien1'' de 9 octets (correspondant au nombre de caractère du nom du fichier cible) n'occupe aucun bloc, il est donc de taille nulle. La véritable taille d'un lien symbolique, dépend du nombre de caractère du nom (chemin) du fichier qu'il cible. Au delà d'un certain nombre de caractère (ici 60), un bloc lui est attribué.\\ \\ La ligne de commande suivante crée deux liens symboliques et affiche leurs détails : * Le premier nommé ''59a'', cible un fichier (inexistant) nommé par 59 caractères (59 a). * Le second nommé ''60a'', cible un fichier (inexistant) nommé par 60 caractères (60 a). (for i in {1..59};do n=a$n;done; ln -s $n 59a; ln -s a$n 60a); ls -lsh 59a 60a 0 lrwxrwxrwx 1 martin martin 59 déc 14 22:15 59a -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 4,0K lrwxrwxrwx 1 martin martin 60 déc 14 22:15 60a -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Tant que le chemin (le nom) de la cible mémorisé par un lien symbolique, ne dépasse pas un certain nombre de caractère (ici 60), il est stocker par l'inode du lien symbolique. Ainsi aucun fichier (bloc) n'est ouvert pour connaître la cible. Seul l'inode est lu. Au delà, un bloc est utiliser. Alors le système doit ouvrir (lire) ce bloc pour accéder à la cible.\\ Voir : [[https://fr.wikipedia.org/wiki/Lien_symbolique#Stockage|(fr) Lien symbolique > Stockage (wikipedia.org)]] La commande ''[[doc:systeme:rm|rm]]'' permet de supprimer des fichiers. rm -v 59a 60a '59a' supprimé '60a' supprimé ==== Modification du nom d'un lien symbolique ==== Modifions le nom du fichier du lien symbolique ''lien1'' à l'aide de la commande [[:doc:systeme:mv |mv]] : mv lien1 lien2 ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:13 lien2 -> test1.txt -rw-r--r-- 1 martin martin 30 déc 14 22:08 test1.txt Tout reste fonctionnel et en place. :-) Pour poursuivre cette illustration dans la clarté, remettons le nommage du lien symbolique ''lien2'' en ''lien1''. mv lien2 lien1 ==== Modification du nom de la cible ==== Modifions le nom du fichier cible ''test1.txt'' : mv test1.txt test2.txt ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:13 lien1 -> test1.txt -rw-r--r-- 1 martin martin 30 déc 14 22:08 test2.txt //Patatras !// Nous voyons alors que le fichier cible ''lien1'' se met en carafe (il alors est écrit en rouge dans le terminal //bash//). Lorsque la cible d'un lien symbolique est manquante, le lien est dit brisé ou cassé. La commande ''file'' le montre : file lien1 lien1: broken symbolic link to test1.txt Puisque le lien est cassé (sa cible n'existe plus), la commande ''cat'' retourne une erreur : cat lien1 cat: lien1: Aucun fichier ou dossier de ce type Ainsi que la commande ''ls -L'' ls -L lien1 ls: impossible d'accéder à 'lien1': Aucun fichier ou dossier de ce type Pour rétablir les choses, ici, il suffit : * De renommer le fichier cible ''test2.txt'' en ''test1.txt'', * Ou bien de recréer le lien symbolique ''lien1'' avec la commande ''ln'',\\ En désignant le fichier cible ''test2.txt''\\ Et en utilisant l'option ''f'' (pour forcer l'écrasement du fichier de destination) :\\ ''ln -sf test2.txt lien1''\\ :!: Attention de ne pas intervertir les deux noms, car sinon ce sera le fichier cible qui sera écrasé. Et tout redevient effectif. Pour la suite du tuto, choisir de remettre le fichier cible en ''test1.txt'' mv test2.txt test1.txt ==== Modifications des droits ==== Depuis le début de cette illustration, nous voyons que les droits restent immuablement complets pour le fichier du lien symbolique ''lien1''. rwx rwx rwx Essayons de les modifier. \\ Modifions la propriété du fichier du lien symbolique ''lien1'' pour que seul le propriétaire puisse y accéder en lecture et écriture. Situation de départ : ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt -rw-r--r-- 1 martin martin 30 déc 14 22:08 test1.txt Les droits d'un fichier sont modifiés avec la commande [[:doc:systeme:chmod|chmod]] : chmod 600 lien1 On obtient alors : ls -l total 4 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt -rw------- 1 martin martin 30 déc 14 22:08 test1.txt Nous voyons que le fichier du lien symbolique ''lien1'' n'est pas affecté par cette modifications des droits : lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt Et que le fichier cible ''test1.txt'' s'en trouve directement rectifié par cette commande exécuter sur le lien symbolique ''lien1'' : -rw------- 1 martin martin 30 déc 14 22:08 test1.txt ==== Copies de lien symbolique ==== La simple copie de lien symbolique produit un nouveau fichier pour chaque lien, identique à la cible. Tout d'abord, créons le répertoire ''rep1''.\\ Puis copions les deux fichiers : mkdir rep1 cp -v lien1 test1.txt rep1 'lien1' -> 'rep1/lien1' 'test1.txt' -> 'rep1/test1.txt' Maintenant listons (avec les détails) le contenu du répertoire ''rep1'' ls -l rep1/* -rw-r--r-- 1 martin martin 30 déc 14 22:20 rep1/lien1 -rw-r--r-- 1 martin martin 30 déc 14 22:20 rep1/test1.txt C'est bien la cible (''test1.txt'') du lien symbolique (''lien1'') qui à été copié dans le répertoire ''rep1'', sous le nom du lien (''lien1''). file rep1/* rep1/lien1: ASCII text rep1/test1.txt: ASCII text ---- L'option ''-P'' ou ''-d'' de la commande ''cp'' permet de préserver les liens symboliques : rm rep1/* cp -vP lien1 test1.txt rep1 'lien1' -> 'rep1/lien1' 'test1.txt' -> 'rep1/test1.txt' Affichage des détails du contenu du répertoire ''rep1'' : ls -l rep1/* lrwxrwxrwx 1 martin martin 9 déc 14 22:22 rep1/lien1 -> test1.txt -rw------- 1 martin martin 30 déc 14 22:22 rep1/test1.txt Ce coup ci, le lien symbolique à été copier exactement comme il est, ciblant le fichier ''test1.txt'' situé dans le même répertoire que lui (dans ''rep1''). file rep1/* rep1/lien1: symbolic link to test1.txt rep1/test1.txt: ASCII text Ici, tout va bien puisque le lien à été copié en même temps que sa cible. ---- Si seul le lien avait été copié, un lien brisé (sans cible) aurait été obtenu : rm rep1/* cp -P lien1 rep1/lien2 ls -l rep1/* lrwxrwxrwx 1 martin martin 9 déc 14 22:24 rep1/lien2 -> test1.txt Le lien à été copié dans le répertoire ''rep1'', mais il est brisé (puisqu'il n'a pas de cible) : file rep1/* rep1/lien2: broken symbolic link to test1.txt Cela provient du fait que le lien originel a été créé en désignant sa cible par un chemin relatif((Un **chemin relatif** désigne un emplacement depuis un répertoire.)). ---- Il en serait autrement si le lien avait été construit en fournissant un chemin absolu((Un **chemin absolu** désigne un emplacement depuis le répertoire racine (''/'').)).\\ Alors il désignerait toujours la même cible, même s'il était copié n'importe où dans l'arborescence. **__note__ :** Le caractère ''~'' (tilde), placé au début d'un chemin, est remplacé durant l'interprétation de //bash//, par le chemin absolu du répertoire personnel de l’utilisateur (ici : ''/homme/martin''). ln -s ~/test_lien/test1.txt lien3 ls -l total 8 lrwxrwxrwx 1 martin martin 9 déc 14 22:05 lien1 -> test1.txt lrwxrwxrwx 1 martin martin 32 déc 14 22:30 lien3 -> /home/martin/test_lien/test1.txt drwxr-xr-x 2 martin martin 4096 déc 14 22:20 rep1 -rw------- 1 martin martin 30 déc 14 22:08 test1.txt Les deux liens symboliques ''lien1'' et ''lien3'' désignent le même fichier cible : ''test1.txt''. * Le premier désigne sa cible avec un chemin relatif (au répertoire ''/home/martin/test_lien'').\\ * Le second désigne sa cible avec un chemin absolu, depuis la racine du système (''/''). Copie du nouveau lien ''lien3'' dans le répertoire ''rep1'' : cp -P lien3 rep1/lien4 file rep1/* rep1/lien2: broken symbolic link to test1.txt rep1/lien4: symbolic link to /home/martin/test_lien/test1.txt Contrairement à la copie du lien ''lien1'' (vers ''rep1/lien2''), la copie du lien ''lien3'' (vers ''rep1/lien4'') à conservé sa cible. cat rep1/lien4 Bonjour toto Comment vas-tu ? ==== Répertoire et lien symbolique ==== Un lien symbolique peut cibler un répertoire. ln -s rep1 lien_rep1 ls -l lien_rep1 lrwxrwxrwx 1 martin martin 4 déc 14 22:40 lien_rep1 -> rep1 Le nouveau lien ''lien_rep1'', à pour cible le répertoire ''rep1''.\\ Il peut-être utilisé pour accéder à sa cible, pour y réaliser toutes sortes d'opérations.\\ Par exemple, en lister le contenu : ls -l lien_rep1/* lrwxrwxrwx 1 martin martin 9 déc 14 22:24 lien_rep1/lien2 -> test1.txt lrwxrwxrwx 1 martin martin 32 déc 14 22:32 lien_rep1/lien4 -> /home/martin/test_lien/test1.txt ---- En utilisant un chemin absolu pour désigner la cible, un lien peut être placé n'importe où : ln -s ~/test_lien /tmp ls -l /tmp/test_lien lrwxrwxrwx 1 martin martin 21 déc 14 22:42 /tmp/test_lien -> /home/martin/test_lien Un lien symbolique qui cible un répertoire, agit comme un répertoire.\\ Il est possible de s'y déplacer : **__Note__ :** La commande **[[doc:systeme:pwd|pwd]]** retourne le chemin du répertoire courant (celui où l'on se trouve). pwd /home/martin/test_lien cd /tmp/test_lien pwd /tmp/test_lien C'est comme si l'on se trouvait dans le répertoire cible : ls -F lien1@ lien3@ lien_rep1@ rep1 test1.txt touch rep1/fichier.txt ls -F ~/test_lien/rep1 fichier.txt lien2@ lien4@ ==== Suppression de lien symbolique ==== Supprimer liens symboliques n'altère en rien un fichier cible : rm -v lien1 lien3 rep1/lien* 'lien1' supprimé 'lien3' supprimé 'rep1/lien2' supprimé 'rep1/lien4' supprimé ls -l test1.txt total 4 -rw------- 1 martin martin 30 déc 14 22:08 test1.txt ---- Ni même un répertoire, lorsque l'on supprime le(s) lien(s) symbolique(e) le ciblant : cd ~/test_lien rm -v /tmp/test_lien lien_rep1 '/tmp/test_lien' supprimé 'lien_rep1' supprimé ls -R ~/test_lien /home/martin/test_lien: rep1 test1.txt ./rep1: fichier.txt **__Note__ :** Pour supprimer un répertoire avec la commande **[[doc:systeme:rmdir|rmdir]]**, le répertoire doit être vide. rm rep1/fichier.txt rmdir rep1 rm test1.txt ===== Les liens physiques (hardlink) : ===== Un lien physique rattache un nom de fichier à un inode. Un inode (un fichier) peut être lié à plusieurs noms dans le même système de fichier.\\ Ainsi, plusieurs noms (chemins) peuvent permettre d'accéder au même fichier (au même inode) **ATTENTION :** Un lien physique à la particularité de devoir se situer __sur le même système de fichier__ que sa cible !\\ \\ L'identifiant d'un inode est unique, uniquement dans le système de fichier au quel il appartient.\\ 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. Commençons par créer un fichier de départ vide, ''test2.txt'' : touch test2.txt Au départ, nous avons donc la situation suivante : ls -l total 0 -rw-r--r-- 1 martin martin 0 déc 15 00:02 test2.txt ==== Créer un lien physique ==== Pour créer un lien physique, on utilise la commande ''ln'' sans l'option ''-s''. ln test2.txt lien2.txt ls -l total 0 -rw-r--r-- 2 martin martin 0 déc 15 00:02 lien2.txt -rw-r--r-- 2 martin martin 0 déc 15 00:02 test2.txt Ah ! Plus de lettre "''l''" ni de "//flèches//" pour indiquer le lien physique. \\ Nous pouvons toutefois distinguer un changement dans le listage des droits des fichiers liés physiquement : Le chiffre ''1'' du second champs, devient ''2'' dans la ligne du fichier ''test2.txt'' :\\ ''-rw-r--r-- **2** martin martin 0 déc 15 00:02 lien2.txt'' Pareillement dans la ligne du ''lien2.txt'' :\\ ''-rw-r--r-- **2** martin martin 0 déc 15 00:02 lien2.txt'' Le second champ retourné par le commande ''ls -l'', indique ne nombre de fois que l'inode d'un fichier est lié à un nom (le nombre de fois où un fichier est lié physiquement).\\ \\ * ''1'' : Quand un fichier ne dispose que de son nom (l'inode de ce fichier n'est lié qu'à un seul nom). * ''2'' : Indique que l'inode de ce fichier est lié à 2 noms. * ''3'' : Indique que l'inode de ce fichier est lié à 3 noms. * Etc. Une autre différence est le partage des droits qui sont là __tout à fait identiques__ entre les fichiers liés physiquement. ==== Modifications du contenu des fichiers ==== Ajoutons du contenu dans l'un puis un second ajout dans l'autre des fichiers liés //physiquement// en vérifiant les contenus à chaque fois : echo Très bien titi ! > lien2.txt ls -l total 8 -rw-r--r-- 2 martin martin 18 déc 15 13:49 lien2.txt -rw-r--r-- 2 martin martin 18 déc 15 13:49 test2.txt cat test2.txt Très bien titi ! echo Et toi Jojo ? >> test2.txt cat lien2.txt Très bien titi ! Et toi Jojo ? ls -l total 8 -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 Toutes les modifications, __ajoutées ou retranchées__ dans chacun des fichiers agira de même dans l'autre. ==== Occupation sur le disque ==== À l'aide de la commande ''ls -li'', nous pouvons voir la taille des fichiers et comparer leurs inodes : ls -li 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 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.\\ 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 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 : ls -lh 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 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'' : ls -lsh 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 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. stat -c "%b (x%B) %n" * 8 (x512) lien2.txt 8 (x512) test2.txt 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). Pour connaître la taille réelle occupée par des fichiers, la commande ''du'' doit être utilisée. du -h * 4,0K lien2.txt 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 : mkdir rep1 cp -v *2.txt rep1 'lien2.txt' -> 'rep1/lien2.txt' 'test2.txt' -> 'rep1/test2.txt' **__Note__ :** L'option ''-c'' de la commande ''du'' demande le total des fichiers listés. du -ch rep1/* 4,0K rep1/lien2.txt 4,0K rep1/test2.txt 8,0K total 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. stat -c "%i %h %n" *.txt rep1/*.txt 8667149 2 lien2.txt 8667149 2 test2.txt 8667652 1 rep1/lien2.txt 8667653 1 rep1/test2.txt 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. ---- L'option ''-l'' de la commande ''cp'' permet de lier physiquement des fichiers au lieu de les copier.\\ (A condition qu'ils soient copiés liés dans le même système de fichier.) rm -v rep1/* 'rep1/lien2.txt' supprimé 'rep1/test2.txt' supprimé cp -vl *2.txt rep1 'lien2.txt' -> 'rep1/lien2.txt' 'test2.txt' -> 'rep1/test2.txt' stat -c "%i %h %n" * rep1/* 8667149 4 lien2.txt 8695636 2 rep1 8667149 4 test2.txt 8667149 4 rep1/lien2.txt 8667149 4 rep1/test2.txt 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 : ln rep1 rep2 ln: rep1 : lien direct non permis pour un répertoire Même //root// ne peut le faire : ln rep1 rep2 ln: rep1 : lien direct non permis pour un répertoire 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) : ls -Ra .: . .. lien2.txt rep1 test2.txt ./rep1: . .. lien2.txt test2.txt .. Ou s'ils sont directement nommés : stat -c "%i %h %n" rep1 rep1/. rep1/.. . ~/test_lien 8695636 2 rep1 8695636 2 rep1/. 8695247 3 rep1/.. 8695247 3 . 8695247 3 /home/martin/test_lien 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 : mkdir -v rep{2..5} 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' stat -c "%i %h %n" ~/test_lien . rep*/.. 8695247 7 /home/martin/test_lien 8695247 7 . 8695247 7 rep1/.. 8695247 7 rep2/.. 8695247 7 rep3/.. 8695247 7 rep4/.. 8695247 7 rep5/.. ---- rmdir rep{2..5} ==== Suppression des fichiers ==== Supprimer des fichiers liés n’altère en rien ceux qui restent. **__Note__ :** La commande ''rm -r ////'' permet de supprimer un répertoire non vide (et tout ce qu'il contient, sous-répertoires compris) rm -rv rep1 'rep1/lien2.txt' supprimé 'rep1/test2.txt' supprimé répertoire 'rep1' supprimé ls -li 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 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 : rm test2.txt ls -li 8667149 -rw-r--r-- 1 martin martin 32 déc 15 13:52 lien2.txt Comme dit le captnfab dans sa relecture : \\ 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). Pour supprimer définitivement des fichiers liés, tous doivent être supprimés. rm lien2.txt ls -l total 0 ===== Conclusion ===== Les liens sont utiles si vous souhaitez qu'un fichier apparaisse dans plusieurs répertoires, ou sous un nom différent. Si le fichier a une assez grande taille vous pouvez envisager, au lieu de copier dans un répertoire donné, de créer un lien réduisant ainsi l'utilisation d'espace disque. 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