Linux-Mandrake: |
Guide de l'utilisateur |
et Manuel de référence |
MandrakeSoft
Janvier 2000 http://www.linux-mandrake.com
/proc
Le Guide de l'utilisateur a introduit les concepts de propriété des fichiers et les droits d'accès, mais pour vraiment comprendre le système de fichiers de Linux, il faut redéfinir la notion même de fichier. Une raison en est que:
Ici, « tout » veut dire vraiment tout. Un disque dur, une partition sur un disque dur, un port parallèle, une connexion à un site web, une carte Ethernet, tous ces éléments sont des fichiers. Même les répertoires sont des fichiers. Linux reconnaît plusieurs types de fichiers, en plus des fichiers réguliers et des répertoires. Notez que par type de fichier ici, nous ne faisons pas référence au type du contenu du fichier: pour Linux et pour tout système Unix, un fichier, qu'il soit une image GIF, un fichier binaire ou autre, est juste une suite d'octets. La différenciation des fichiers en fonction de leur contenu est laissé aux applications.
Si vous vous souvenez, quand vous tapez ls -l
, le caractère
avant les droits d'accès représente le type du fichier. Nous avons déjà
vu deux types de fichiers: les fichiers réguliers (-
) et les
répertoires (d
). Vous pouvez aussi tomber sur les suivants si
vous vous baladez dans l'arborescence et listez le contenu des
répertoires:
/dev/null
, que nous avons
déjà vu), ou des périphériques (ports série ou parallèle), qui ont en
commun la particularité que leur contenu (s'ils en ont) n'est pas
conservé en mémoire[13]. De tels fichiers sont identifiés
par la lettre 'c'
.
/dev/hda
, /dev/sda5
sont des exemples
de fichiers en mode bloc. Sur la sortie d'un ls -l
, ces
fichiers sont identifiés par la lettre 'b'
.
'l'
.
'p'
.
's'
.Voici un exemple de chacun de ces fichiers:
$ ls -l /dev/null /dev/sda /etc/rc.d/rc3.d/S20random /proc/554/maps \
/tmp/ssh-fg/ssh-510-agent
crw-rw-rw- 1 root root 1, 3 mai 5 1998 /dev/null
brw-rw---- 1 root disk 8, 0 mai 5 1998 /dev/sda
lrwxrwxrwx 1 root root 16 déc 9 19:12 /etc/rc.d/rc3.d/S20random ->
../init.d/random*
pr--r--r-- 1 fg fg 0 déc 10 20:23 /proc/554/maps|
srwx------ 1 fg fg 0 déc 10 20:08
/tmp/ssh-fg/ssh-510-agent=
$
On devrait ajouter que ext2fs, comme tous les autres systèmes de fichiers Unix, stocke les fichiers, quel que soit leur type, dans une table des i-noeuds. Une particularité est qu'un fichier n'est pas identifié par son nom, mais par un numéro d'i-noeud. En fait, certains fichiers n'ont pas de noms. Les noms sont juste une conséquence d'une notion plus large:
Le meilleur moyen de comprendre ce qui se cache derrière cette notion de liens est de prendre un exemple. Créons un fichier (régulier):
$ pwd
/home/fg/exemple
$ ls
$ touch a
$ ls -il a
32555 -rw-rw-r-- 1 fg fg 0 déc 10 08:12 a
L'option -i
de la commande ls
affiche le numéro
d'i-neud, qui est le premier champ dans la sortie. Comme vous pouvez le
voir, avant que nous ayons créé le fichier a
, il n'y avait aucun
fichier dans le répertoire. L'autre champ intéressant est le troisième,
qui est le compteur de liens pour le fichier.
En fait, on peut séparer la commande touch a
en deux actions
distinctes:
a
, dans le
répertoire courant, /home/fg/exemple
. Donc, le fichier appelé
/home/fg/exemple/a
est un lien vers l'i-noeud de numéro 32555,
et c'est pour l'instant le seul: le compteur de liens est à 1.Mais maintenant, si nous faisons:
$ ln a b
$ ls -il a b
32555 -rw-rw-r-- 2 fg fg 0 déc 10 08:12 a
32555 -rw-rw-r-- 2 fg fg 0 déc 10 08:12 b
$
nous avons créé un autre lien vers le même i-noeud. Comme vous pouvez
le voir, nous n'avons créé aucun fichier nommé b
, mais au lieu de
cela nous avons ajouté un autre lien vers l'i-noeud de numéro 32555
dans le même répertoire nommé b
. Vous pouvez voir dans la
deuxième sortie de ls -l
que le compteur de liens est
maintenant 2 et non plus 1.
Maintenant, si nous faisons:
$ rm a
$ ls -il b
32555 -rw-rw-r-- 1 fg fg 0 déc 10 08:12 b
$
nous voyons que même si nous avons effacé le « fichier
original », l'i-noeud existe encore. Mais maintenant le seul lien vers
cet i-noeud est /home/fg/exemple/b
.
Donc, un i-noeud est lié si et seulement si il est référencé
par un nom au moins une fois dans un répertoire quelconque[15].
Les répertoires eux-mêmes sont aussi stockés dans des i-noeuds, mais
leur compteur de liens, contrairement à tous les autres types de
fichiers, est leur nombre de sous-répertoires. Il y a au moins deux
liens par répertoire: le répertoire lui-même (.
) et son
répertoire parent (..
).
Des exemples typiques de fichiers qui ne sont pas liés (c'est-à-dire
qu'ils n'ont pas de noms) sont les connexions réseau: vous ne verrez
jamais le fichier correspondant à votre connexion à
www.linux-mandrake.com
dans votre arborescence, quel que soit le
répertoire que vous essayiez. De façon similaire, quand vous utilisez un
tube dans le shell, le fichier correspondant au tube
existe bien, mais il n'est pas lié.
Revenons à l'exemple des tubes, car il est très intéressant et c'est également une bonne illustration de la notion de liens. Quand vous utilisez un tube dans une ligne de commande, le shell crée le tube pour vous et fait en sorte que la commande avant le tube écrit dans celui-ci, tandis que la commande après le tube y lit ses données. Tous les tubes, qu'ils soient anonymes (comme ceux utilisés par le shell) ou nommés (voyez ci-dessous), fonctionnent selon le principe FIFO (First In, First Out, "premier arrivé, premier servi"). Nous avons déjà vu des exemples sur l'utilisation des tubes avec le shell, mais prenons-en un dans un but d'illustration:
$ ls -d /proc/[0-9] | head -6
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
Une chose que vous ne remarquez pas dans cet exemple (parce que cela se
passe trop vite) est que les écritures sur le tube sont bloquantes. Cela
veut dire que quand la commande ls
écrit dans le tube, elle
est bloquée jusqu'à ce qu'un processus à l'autre bout lise depuis le
tube. Pour visualiser cet effet, vous pouvez créer des tubes nommés,
qui, contrairement aux tubes utilisés par le shell, ont des noms
(donc ils sont liés, tandis que les tubes utilisés par le shell
ne le sont pas). La commande pour créer de tels tubes est
mkfifo
:
$ mkfifo un_tube
$ ls -il
total 0
169 prw-rw-r-- 1 fg fg 0 déc 10 14:12 un_tube|
#
# Vous pouvez voir que le compteur de liens est 1, et que la sortie
# montre que le fichier est un tube ('p').
#
# Vous pouvez aussi utiliser ln ici :
#
$ ln un_tube le_même_tube
$ ls -il
total 0
169 prw-rw-r-- 2 fg fg 0 déc 10 15:37 un_tube|
169 prw-rw-r-- 2 fg fg 0 déc 10 15:37 le_même_tube|
$ ls -d /proc/[0-9] >un_tube
#
# Le processus est bloqué, comme il n'y a pas de lecteurs à l'autre
# bout. Tapez C-z pour suspendre le processus...
#
zsh: 3452 suspended ls -d /proc/[0-9] > un_tube
#
# ...Puis mettez-le en tâche de fond :
#
$ bg
[1] + continued ls -d /proc/[0-9] > un_tube
#
# Maintenant lisez depuis le tube...
#
$ head -6 <le_même_tube
#
# ...le processus écrivain se termine :
#
[1] + 3452 done ls -d /proc/[0-9] > un_tube
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
$
De la même façon, les lectures sont bloquantes. Si nous exécutons les
commandes ci-dessus dans l'ordre inverse, nous observons que
head
est bloqué, en attendant qu'un processus lui donne
quelque chose à lire:
$ head -6 <un_tube
#
# Le processus est bloqué, suspendez-le : C-z
#
zsh: 741 suspended head -6 < un_tube
#
# Mettez-le en tâche de fond...
#
$ bg
[1] + continued head -6 < un_tube
#
# ...Et donnez-lui à manger :)
#
$ ls -d /proc/[0-9] >le_même_tube
$ /proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1] + 741 done head -6 < un_tube
$
Vous pouvez aussi voir un effet indésirable dans cet exemple: la
commande ls
a fini son exécution avant que la commande
head
prenne le relais. La conséquence est que vous êtes
retourné(e) au prompt immédiatement, mais head
ne s'est
exécuté qu'après. Donc il a effectué sa sortie seulement après que vous
ayez récupéré le prompt :)
Comme il a déjà été dit, de tels fichiers sont soit des fichiers créés par le système, soit bien des périphériques de votre machine. Nous avons aussi mentionné que le contenu des fichiers en mode bloc était gardé en mémoire alors que tel n'était pas le cas des fichiers en mode caractère. Pour illustrer ceci, insérez une disquette quelconque dans le lecteur et tapez la commande suivante deux fois de suite:
$ dd if=/dev/fd0 of=/dev/null
Vous pouvez observer la chose suivante: tandis que, la première fois que la commande a été lancée, tout le contenu de la disquette a été lu, la deuxième fois il n'y a eu aucun accès au lecteur de disquette. C'est simplement parce que le contenu de la disquette a été gardé en mémoire quand vous avez lancé la commande la première fois --- et que vous n'avez pas changé de disquette entre temps.
Mais maintenant, si vous voulez imprimer un gros fichier de cette façon (si, ça fonctionne):
$ cat /un/gros/fichier/imprimable/quelque/part >/dev/lp0
la commande prendra autant de temps que vous la tapiez une, deux ou
cinquante fois. Ceci est dû au fait que /dev/lp0
est un fichier
en mode caractère, et son contenu n'est pas gardé en mémoire.
Le fait que le contenu des fichiers en mode bloc soit gardé en mémoire a un effet de bord agréable: non seulement les lectures sont gardées en mémoire, mais c'est aussi le cas des écritures. Cela autorise les écritures sur disque à être asynchrones: quand vous écrivez un fichier sur disque, l'opération d'écriture elle-même ne sera pas faite immédiatement. Elle n'aura lieu que quand Linux le décidera.
Enfin, chacun de ces fichiers spéciaux possède un numéro majeur
et un numéro mineur. Sur la sortie d'un ls -l
, ils
apparaissent en lieu et place de la taille, étant donné que la taille
pour de tels fichiers est hors de propos:
$ ls -l /dev/hda /dev/lp0
brw-rw---- 1 root disk 3, 0 mai 5 1998 /dev/hda
crw-rw---- 1 root daemon 6, 0 mai 5 1998 /dev/lp0
Ici, les numéros majeur et mineur de /dev/hda
sont respectivement
3 et 0, tandis que ce sont respectivement 6 et 0 pour /dev/lp0
.
Notez que ces numéros sont uniques par catégorie de fichier, ce qui veut
dire qu'il peut exister un fichier en mode caractère ayant 3 pour majeur
et 0 pour mineur (un tel fichier existe : c'est /dev/ttyp0
), et
de la même façon il peut y avoir un fichier en mode bloc ayant 6 pour
majeur et 0 pour mineur. Ces nombres existent pour une raison bien
simple: cela permet à Linux d'associer les bonnes opérations aux
fichiers (donc aux péripériques auxquels ces fichiers se réfèrent). On
ne contrôle pas un lecteur de disquettes de la même façon que, par
exemple, un disque dur SCSI.
Ici nous avons à faire face à une incompréhension très courante, même parmi les utilisateurs d'Unix, qui est principalement due au fait que les liens tels que nous les avons vus jusque là (faussement appelés liens « en dur ») sont seulement associés aux fichiers réguliers (et nous avons vu que ce n'est pas le cas --- même les liens symboliques sont « liés »). Mais cela requiert que nous expliquions d'abord ce que sont les liens symboliques[16].
Les liens symboliques sont des fichiers d'un type particulier dont le seul contenu est une chaîne de caractères arbitraire, qui peut ou non pointer sur un vrai nom de fichier. Quand vous mentionnez un lien symbolique sur la ligne de commande ou dans un programme, vous accédez en fait au fichier sur lequel pointe le lien, s'il existe. Par exemple:
$ echo Bonjour >monfichier
$ ln -s monfichier monlien
$ ls -il
total 4
169 -rw-rw-r-- 1 fg fg 6 déc 10 21:30 monfichier
416 lrwxrwxrwx 1 fg fg 6 déc 10 21:30 monlien -> monfichier
$ cat monfichier
Bonjour
$ cat monlien
Bonjour
Vous pouvez voir que le type du fichier monlien
est
'l'
. Les droits d'accès pour un lien symbolique n'ont aucune
signification: ils seront toujours rwxrwxrwx
. Vous pouvez
également voir que c'est un fichier différent de monfichier
,
parce que son numéro d'i-noeud est différent. Mais il se réfère au
fichier monfichier
de façon symbolique, donc quand vous tapez
cat monlien
, vous affichez en fait le contenu du fichier
monfichier
. Pour démontrer qu'un lien symbolique contient une
chaîne arbitraire, nous pouvons faire la chose suivante:
$ ln -s "Je n'existe pas" unautrelien
$ ls -il unautrelien
747 lrwxrwxrwx 1 fg fg 15 déc 15 18:01 unautrelien -> Je n'existe pas
$ cat unautrelien
cat: unautrelien: Aucun fichier ou répertoire de ce type
$
Mais les liens symboliques existent parce qu'ils s'affranchissent de plusieurs limitations des liens normaux:
Donc les liens symboliques sont très utiles dans plusieurs cas, et très
souvent, les gens tendent à les utiliser pour lier des fichiers même
quand un lien normal est possible. Un avantage des liens normaux,
pourtant, est que vous ne perdez pas le fichier si vous effacez
l'« original » :)
Enfin, si vous avez observé attentivement, vous savez à quoi correspond la taille d'un lien symbolique: c'est tout simplement la taille de la chaîne de caractères.
De même que la FAT a des attributs de fichiers (archive, fichier système, invisible), ext2fs a aussi les siens propres, mais ils sont différents. Non en parlons pour être complet, mais ils sont très peu utilisés. Toutefois, si vous voulez un système vraiment sécurisé, continuez la lecture.
Il existe deux commandes pour manipuler les attributs: ce sont
lsattr(1)
et chattr(1)
. Vous l'aurez deviné,
lsattr
LiSte les attributs, et
chattr
les CHange. Ces attributs
s'appliquent seulement aux répertoires et aux fichiers réguliers. Ce
sont les suivants:
A
(no Access time,
« pas de date d'accès »): Si un fichier ou un répertoire a cet
attribut positionné, quand on y accédera, que ce soit en lecture ou en
écriture, sa date de dernier accès ne sera pas mise à jour. Cela peut
être utile, par exemple, sur des fichiers ou répertoires qui sont très
souvent accédés en lecture, en particulier parce que ce paramètre est le
seul à changer sur un i-noeud quand celui-ci est ouvert en lecture
seule.
a
(append only,
« uniquement pour ajout »): Si un fichier a cet attribut
positionné et est ouvert en écriture, la seule opération possible sera
d'ajouter des données à la fin du fichier. Pour un répertoire, cela
signifie que vous pouvez seulement y ajouter des fichiers, mais vous ne
pouvez ni renommer des fichiers déjà existants ni en effacer. Seul
root
peut positionner ou enlever cet attribut.
d
(no dump,
« pas de sauvegarde »): dump(8)
est
l'utilitaire Unix standard pour faire des sauvegardes. Il
sauvegarde tout système de fichiers pour lequel le compteur de
sauvegarde est à 1 dans /etc/fstab
(voyez le
chapitre 33.0). Mais si un fichier ou répertoire a
cet attribut positionné, contrairement aux autres, il ne sera pas pris
en compte lors d'une sauvegarde. Notez que pour les répertoires, cela
inclut également tous les sous-répertoires et fichiers en-dessous de
celui-ci.
i
(immutable,
« immuable »): Un fichier ou répertoire avec cet attribut
ne peut tout simplement pas être modifié: il ne peut pas être renommé,
on ne peut y ajouter aucun lien[17], et on ne peut pas l'effacer. Seul root
peut positionner ou enlever cet attribut. Notez que cela empêche
également les changements à la date de dernier accès, donc vous n'avez
pas besoin de positionner l'attribut A
quand cet attribut-ci
est positionné.
s
(secure deletion,
« sécurité pour l'action d'effacer »): Quand un fichier ou
un répertoire avec cet attribut est effacé, les blocs qu'il occupait sur
disque sont remplis de zéros.
S
(Synchronous mode,
« mode synchrone »): Quand un fichier ou répertoire a cet
attribut positionné, toutes les modifications qui y sont apportées sont
synchrones et écrites immédiatement sur disque.Vous pouvez, par exemple, placer l'attribut 'i'
sur des
fichiers système essentiels pour éviter les mauvaises surprises. Pensez
aussi à l'attribut 'A'
pour les pages de manuel par exemple:
cela évitera beaucoup d'activité disque, et, en particulier, cela
prolongera la durée de vie de la batterie sur les portables.
/proc