Liens, liens symboliques et liens en dur

Un article de Wiki de la communauté Mandriva.

Jump to: navigation, search

CETTE PAGE EST UNE VERSION RÉVISÉE ET MISE À JOUR DE CETTE PAGE MAINTENANT OBSOLÈTE DE L'ANCIENNE BASE DE CONNAISSANCES :

http://club.mandriva.com/xwiki/bin/view/KB/Links ptyxs 4 février 2008 à 10:51 (CET)


Sommaire

[modifier] De l'utilité des liens

Un lien est comme une sorte de « poignée » qui conduit à un fichier (ou à un répertoire). A quoi cela sert-il ?


[modifier] Un seul exemplaire vaut mieux que plusieurs

Un document de travail, un fichier qu'on consulte souvent, il est parfois utile de l'avoir sous la main dans différents répertoires, si l'on veut pouvoir l'ouvrir très vite dans des contextes divers, que l'on soit en ligne de commande ou dans un navigateur de fichiers comme Konqueror. Mais il est, en général, très malsain de multiplier des copies identiques d'un même fichier en différents points du système : imaginez que par mégarde ce fichier reçoive des modifications différentes sur des copies distinctes, ce serait la porte ouverte à une épouvantable confusion...


Il vaut donc mieux entreposer une unique copie de ce fichier quelque part sur le disque, avec des liens qui pointent vers lui, disséminés ici ou là en fonction des besoins.


[modifier] Gagner de la place

Un lien a du reste un volume extrêmement « petit » et ne prend qu'une place négligeable sur le disque, créer un lien consomme donc en général beaucoup moins d'espace sur le disque qu'effectuer une copie complète d'un fichier.


[modifier] Réunir en un même répertoire des liens vers des fichiers qui ont « quelque chose en commun »

Les répertoires du système Linux et ceux des applications contiennent aussi de nombreux exemples de liens.


Le répertoire /usr/bin, par exemple, contient notamment des liens vers des scripts de démarrage d'applications (voir La hiérarchie du système de fichiers#Où se trouvent les applications ?).


Un cas classique et particulièrement sophistiqué de regroupement de liens par répertoires concerne les « niveaux d'exécution » du système. Le répertoire /etc/rc.d contient des sous-répertoires rc0.d, rc1.d etc. jusqu'à rc6.d. Chacun de ces répertoires est destiné à abriter des liens vers les scripts lançant les différents services qui doivent être activés dans le niveau d'exécution considéré (niveau 0 pour rc0.d, niveau 1 pour rc1.d etc.), ainsi que des liens vers les scripts des services qui doivent être désactivés dans ce niveau d'exécution. L'astuce (une des astuces plutôt) est que c'est le nom même du lien qui indique au système s'il doit invoquer le script avec l'argument start pour lancer le service ou l'argument stop pour l'arrêter !! Et c'est aussi le nom du lien qui détermine l'ordre dans lequel les services seront lancés et désactivés… Ingénieux ce Linux, décidément, non ?

[modifier] Pointer vers le fichier ou le répertoire « par défaut »

Lorsque vous disposez sur votre machine de plusieurs versions d'un logiciel ou d'une bibliothèque, il peut être utile de définir parmi elles une « version par défaut » qui sera invoquée sauf indication contraire explicite.


Par exemple, il n'est pas rare que vous disposiez dans votre répertoire /boot de plusieurs versions du noyau Linux. L'une d'elles est la version par défaut, ce sera toujours celle vers laquelle pointe le lien /boot/vmlinuz.


Plus modestement, vous trouverez dans la page sur l'installation d'une application via une archive tar.gz, une utilisation intéressante des liens pour le lancement d'une application. Au point 7 est proposée la création d'un lien vers le script de démarrage de l'application, lien qui sera utilisé pour lancer l'application en console aussi bien que par clic sur une icône du bureau ou de la barre des tâches. L'astuce est alors que ce lien s'appuie lui-même sur un lien intermédiaire (créé au point 6) vers le répertoire par défaut de l'application, celui qui sera activé 'normalement', sauf choix explicite d'une autre des versions qui sont installées sur votre système. Il vous sera ainsi possible d'avoir simultanément plusieurs versions installées pour la même application (la dernière version stable et des versions plus anciennes, des versions dans différentes langues, des version bêta etc.) tout en ayant une « version par défaut » définie par ce vers quoi pointe le lien intermédiaire… Ingénieux aussi...


Une utilisation intéressante des liens dans le cadre de la gestion des bibliothèques du système est décrite à cette section sur les conflits entre versions de bibliothèques.


Sous Linux, il existe deux sortes de liens dont nous allons passer en revue les principales propriétés : les liens symboliques et les liens en dur, que nous allons apprendre à bien distinguer dès la section suivante.

[modifier] Liens symboliques et liens en dur

Sous Linux, il existe deux sortes de liens, les liens symboliques (aussi appelés symlinks) et les liens en dur (aussi appelés liens matériels, ou liens physiques ou même, dans certains messages d'erreur de Mandriva liens directs; en anglais hard links).


Sans entrer dans des explications techniques ou théoriques, nous voudrions simplement signaler brièvement ici leurs principales propriétés, celles qui permettent de bien les différencier et de les utiliser.

[modifier] « Voir » la différence...

La différence entre les deux types de lien apparaît de façon immédiatement visible dans l'affichage résultant de la commande ls utilisée avec les options appropriées, comme nous allons le voir tout de suite.


On peut créer les deux sortes de liens à l'aide de la commande ln. Avec l'option -s un lien symbolique sera créé, sans cette option on obtiendra un lien en dur.


Illustrons.


Supposons que le fichier charlotte3.txt existe dans notre répertoire de travail. La commande ls -li (l'option -i entraîne l'affichage, en début de ligne, du « numéro d'inode » de chaque fichier ou répertoire; le numéro d'inode est un numéro que le système attribue à chaque fichier ou répertoire) pourra donner, par exemple, pour ce fichier :


1606777 -rw-r--r--  1 toto toto  3407 fév 27 12:57 charlotte3.txt

(le numéro d'inode du fichier est dans notre exemple 1606777). Créons un lien symbolique charlotte vers ce fichier (grâce à l'option -s de la commande ln), ainsi qu'un lien en dur best_charlotte (ce que nous obtenons avec ln employée sans option) :

Image:Konsole.png
[utilisateur@ordi ~]$ ln -s charlotte3.txt charlotte
Image:Konsole.png
[utilisateur@ordi ~]$ ln charlotte3.txt best_charlotte

le tube :

 ls -li | sort -n 

(où sort -n effectuera un classement par numéro d'inode) pourra maintenant donner quelque chose comme ceci :

1606777 -rw-r--r--  2 toto toto  3407 fév 27 12:57 best_charlotte
1606777 -rw-r--r--  2 toto toto  3407 fév 27 12:57 charlotte3.txt
1610496 lrwxrwxrwx  1 toto toto    14 fév 28 14:52 charlotte -> charlotte3.txt

On voit d'abord que :


  • la ligne correspondant au fichier original (charlotte3.txt) et la ligne correspondant au lien en dur (best_charlotte) se ressemblent énormément : le lien en dur apparaît comme un second nom pour le même fichier.


Notez en particulier que fichier d'origine et lien en dur récemment créé ont :


  • le même numéro d'inode (alors que le lien symbolique a un numéro d'inode qui lui est propre)
  • le même type de fichier, ici « fichier régulier » indiqué par le tiret en tête des permissions, alors que le lien symbolique a un type différent (l pour : « lien symbolique »)
  • le même volume (3407 octets) - alors que le lien symbolique a un tout « petit » contenu (14 octets).
  • le même horodatage (alors que le lien symbolique affiche l'heure et la date de sa création).


Enfin, on remarque, à la fin de la ligne du lien symbolique, une flèche en direction du chemin du fichier vers lequel le lien pointe, alors qu'on n'a rien de tel dans la ligne du lien en dur best_charlotte.


Pour mémoire, avant la création du lien en dur pour charlotte3.txt on avait ceci :

1606777 -rw-r--r--  1 toto toto  3407 fév 27 12:57 charlotte3.txt

et maintenant :

1606777 -rw-r--r--  2 toto toto  3407 fév 27 12:57 charlotte3.txt

Quelle est la différence ??

Le nombre qui précède immédiatement toto est passé de 1 à 2 :


  • la commande ls affiche devant le nom du propriétaire d'un fichier le nombre de « noms » que ce fichier possède : chaque création d'un nouveau lien en dur incrémente (augmente) donc ce nombre d'une unité.


Notez qu'en revanche le lien symbolique n'a pour l'instant qu'un seul nom, lui, le sien...


Question :

Sachant tout ce que nous savons, si nous découvrons par un ls -li qu'un certain fichier possède 4 « noms », comment trouver les 3 autres ??

Réponse : Puisque tous les « noms » possèdent le même numéro d'inode, il suffit d'utiliser - sous root si vous cherchez sur tout le système - la commande find avec l'option -inum :

Image:Konsole.png
[root@ordi ~]# find / -inum numero_d_inode

[modifier] Liens vers un répertoire

Un lien symbolique peut pointer vers un fichier ou vers un répertoire. Un lien en dur pointe uniquement vers un fichier, jamais vers un répertoire.


A noter : Le nombre qui précède le nom du propriétaire dans une ligne obtenue par la commande ls représente :
  • pour un fichier : le nombre de « noms » du fichier (incluant les « liens en dur »)
  • pour un répertoire : le nombre des sous-répertoires qu'il contient (y inclus les deux répertoires cachés bien connus que tout répertoire contient sous Linux :./  (le répertoire lui-même) et ../  (le répertoire parent)) : dans ce cas le décompte ne concerne pas des liens en dur.

[modifier] Le respect des frontières : liens et partitions

Un lien en dur ne peut pointer que vers un fichier qui se trouve sur la même partition que lui, une telle contrainte ne vaut pas pour les liens symboliques.

[modifier] Et si j'efface l'original ?

Si, dans l'exemple qui précède, j'efface le fichier original charlotte3.txt, les conséquences sont radicalement différentes selon les types de lien :

  • le lien symbolique charlotte pointe désormais dans le vide, on ne peut plus accéder au contenu du fichier par son entremise. Il devient en fait inutilisable. La gestion par défaut des couleurs des affichages de ls, sous Mandriva, signale cela par un affichage blanc clignotant sur fond marron.
  • En revanche, le lien en dur best_charlotte nous permet toujours d'accéder tout à fait normalement au contenu du fichier effacé charlotte3.txt et on peut même reconstituer ce dernier tout simplement par copie.


Un fichier ne sera définitivement irrécupérable que lorsque le dernier de tous ses liens en dur présents sur sa partition aura été effacé.

[modifier] Et si je déplace l'original ?

Ma foi, déplacer, en un sens, c'est effacer et copier ailleurs… et ce qui vient d'être dit de l'effacement vaut donc aussi du déplacement. Si je déplace charlotte3.txt le lien symbolique charlotte devient inutilisable, en revanche le lien en dur best_charlotte n'est pas affecté.

[modifier] Et si le fichier original est dans un répertoire interdit ?

Si un lien symbolique pointe vers un fichier qui se trouve dans un répertoire pour lequel vous n'avez pas de permissions d'accès appropriées, vous ne pourrez pas davantage accéder au fichier par le lien que par un accès direct à l'original.

En revanche, vous pourrez accéder au fichier par un lien en dur, si vous avez les permissions pour lire le fichier lui-même : peu importe alors que le lien en dur accessible ait été créé par root à partir du répertoire d'un autre utilisateur qui vous est interdit. Le lien en dur peut donc être un bon moyen de circonvenir cette interdiction (cela peut donc être un bon moyen pour mettre à la disposition d'un autre utilisateur un fichier qui est dans votre répertoire personnel, et cela le sera d'autant plus que le fichier sera très volumineux, une image ISO par exemple, qui ainsi n'aura pas à être copiée).

[modifier] Copier un lien

Pour la copie d'un lien en dur voir Copie de fichiers ou de répertoires#Copier des liens en dur et Copie de fichiers ou de répertoires#L'option -d.


Pour la copie d'un lien symbolique voir Copie de fichiers ou de répertoires#Copier des liens symboliques, ainsi que Copie de fichiers ou de répertoires#L'option -P, et Copie de fichiers ou de répertoires#L'option -R.

[modifier] Utilité de l'un et de l'autre

Les liens symboliques sont apparemment plus couramment utilisés que les liens en dur.


Les exemples de liens auxquels nous avons renvoyé, dans la première section de cette page : #De l'utilité des liens, sont en fait des exemples de liens symboliques.


Un exemple d'emploi de lien en dur est suggéré à la section #Et si le fichier original est dans un répertoire interdit ?. Etant donné qu'ils permettent de « récupérer » le contenu d'un fichier effacé, il a parfois été proposé d'utiliser les liens en dur comme une sorte de « sauvegarde » partielle (voir Une protection contre les effacements accidentels).


Vous trouverez dans cette petite section, des exemples intéressants de l'utilisation des liens symboliques par le système pour gérer les différentes versions des « bibliothèques » auxquelles ont recours les logiciels installés sur votre machine. Cette section concerne, en principe, la compilation, mais il peut être intéressant et utile de la lire même si vous n'envisagez pas à court terme de vous lancer dans cet exercice.


Ce qui précède devrait vous guider dans l'utilisation de l'un et de l'autre.

[modifier] Fournir un lien symbolique comme argument à une commande

[modifier] Prendre en compte le lien ou ce vers quoi il pointe ?

Lorsqu'une commande du shell accepte un fichier ou un répertoire comme argument, la question peut se poser à l'utilisateur de savoir ce qui se passerait si l'on mettait dans la ligne de commande, en position d'argument, non plus un fichier ou un répertoire, mais un lien symbolique pointant vers un fichier ou un répertoire.


La commande prendra-t-elle alors en compte le lien lui-même ou ce vers quoi il pointe ??


Eh bien, cela dépend...


Certaines commandes prennent en compte, « par défaut », c'est-à-dire dans leur emploi « normal », ce vers quoi pointe le lien, d'autres considèrent au contraire uniquement que l'argument est le lien lui-même.


Prenons deux exemples très simples. Ces deux exemples impliquent des liens symboliques pointant vers des fichiers (et non des répertoires).


La commande rm qui permet d'effacer un fichier, appliquée à un argument qui a le statut de lien symbolique pointant vers un fichier, effacera le lien lui-même et n'affectera pas le fichier vers lequel pointait ce lien (ce qui paraît d'une prudence raisonnable...).


La commande cat, au contraire, qui envoie vers la « sortie standard » (stdout), c'est-à-dire le plus souvent vers l'écran, le contenu d'un fichier texte qu'on lui passe en argument, affichera le contenu du fichier texte vers lequel pointerait un lien qu'on lui passerait en argument (elle n'afficherait pas les quelques octets contenus dans le lien lui-même).


rm opère donc, du moins dans ce cas, sur le lien lui-même, (attention : si le lien pointe vers un répertoire, il en va différemment !), tandis que cat opère sur le fichier vers lequel pointe le lien.


La morale de tout ceci est que si vous utilisez une commande de telle sorte qu'elle porte sur un vaste ensemble d'arguments, soit parce que la commande est récursive (et peut donc affecter des répertoires et tout leur contenu, y compris leurs sous-répertoires et ce qu'ils contiennent eux-mêmes), soit parce que vous avez recours à l'expansion des noms de fichiers, alors il peut être prudent de vous renseigner, en regardant les pages de man ou d'info, sur le comportement qu'adoptera la commande si, parmi les divers arguments qui lui sont ainsi passés, figurent des liens symboliques.


Si le comportement par défaut de la commande vis-à-vis des liens symboliques vous convient, parfait. Mais, si ce n'est pas le cas, notez que, bien souvent, ce comportement par défaut pourra être modifié par certaines options passées à la commande (un exemple particulièrement riche : les options de la commande cp). Encore une fois, regardez alors de près la documentation de la commande qui vous intéresse.

[modifier] Un cas compliqué : la commande cd

Cela dit, les choses peuvent être un peu plus compliquées.


Par exemple, si un lien symbolique lien_lien pointe vers un répertoire, une commande cd lien_lien fera du répertoire vers lequel pointe lien_lien votre répertoire de travail.

MAIS notez que, dans ce cas, l'invite du shell, si vous l'avez configurée pour qu'elle affiche le nom et le chemin du répertoire de travail, ou la commande pwd, vous donneront ensuite, par défaut, pour votre nouveau répertoire de travail, le nom et le chemin du lien (et une commande comme cd .. qui vous place dans le répertoire parent agira en conséquence).

En revanche si vous utilisez l'option -P ainsi : cd -P lien_lien alors vous aurez une invite et un pwd qui correspondront exactement au répertoire où vous vous trouverez et qui ne tiendront pas compte du nom et du chemin du lien qui vous a permis d'y accéder.


Si lien_lien pointe vers le répertoire /home/toto/condiments/, voici donc ce qui pourra se passer :

[toto@localhost ~] cd lien_lien
[toto@localhost ~/lien_lien] pwd
/home/toto/lien_lien
[toto@localhost ~] cd -P lien_lien
[toto@localhost ~/condiments] pwd
/home/toto/condiments

Dans les deux cas vous « serez » dans /home/toto/condiments/ après exécution de cd et si vous créez un fichier, disons par une commande touch oignons.txt, ce fichier se trouvera dans les deux cas créé à la racine de /home/toto/condiments/.

[modifier] Lien ou répertoire pointé : le rôle de la barre oblique

Notez, pour terminer, que pour certaines commandes, si le nom d'un lien qui pointe vers un répertoire est passé « tout sec », « réduit à lui-même », c'est le lien qui sera considéré comme argument, alors que si le nom du lien passé en argument est suivi d'une barre oblique (/), ce sera alors le répertoire vers lequel pointe le lien qui sera en fait considéré comme argument.


Par exemple, on le sait, on peut donner un répertoire comme argument à la commande ls, pour que celle-ci affiche la liste des fichiers et sous-répertoire à la racine de l'argument. Le résultat sera le même, que le nom du répertoire soit suivi d'une barre oblique ou non. Ainsi, si le répertoire condiments est à la racine de votre répertoire de travail, les commandes :

ls condiments

et

ls condiments/

donneront le même résultat.


Mais, si cond est un lien symbolique vers le répertoire condiments, alors :

ls cond

affichera simplement le nom du lien cond, tandis que :

ls cond/

affichera le contenu du répertoire condiments vers lequel pointe cond...


Vous pourrez vérifier que la commande find adopte un comportement analogue. Vous en trouverez une application dans le script aSauver.sh attaché à la page Une protection contre les effacements accidentels.