Les liens matériels comptent-ils comme des fichiers normaux?

21

Je me demandais s'il y avait un moyen de l'enregistrer, mais comme la plupart des moteurs de recherche modernes ne fonctionnent pas bien avec des phrases de plus de 5 mots environ, j'ai besoin d'aide sur celui-ci.

Je me demandais cela parce que je fais un script bash qui doit enregistrer des fichiers comme certains types et prendre des décisions en conséquence. Techniquement, cela n'est pas important pour mon projet, mais j'étais curieux.

De plus, s'ils sont considérés comme des fichiers normaux, existe-t-il un moyen de vérifier si ces fichiers sont liés de manière fixe sans avoir à analyser ls -i? Et existe-t-il un moyen de vérifier si un fichier arbitraire, X, est lié à un autre fichier arbitraire, Y, sans utiliser la find -icommande?

Mr. Minty Fresh
la source
5
Avec des liens durs, "X" n'est pas vraiment lié à "Y". "X" et "Y" sont le même fichier.
jordanm
6
Tous les "fichiers normaux" d'un répertoire sont des liens durs. Certains de ces fichiers en ont plusieurs.
Andrew Henle
@AndrewHenle Wow, bon point. C'est exactement le genre de chose que je cherchais, alors merci.
M. Minty Fresh
2
@ Mr.MintyFresh En particulier, il n'y a pas de distinction entre "l'original" et le "lien" comme c'est le cas pour les liens symboliques.
Random832

Réponses:

38

Dans les systèmes de type Unix, la structure de données qui représente les objets du système de fichiers (en d'autres termes, les données sur un fichier), est stockée dans ce qu'on appelle un "inode".

Un nom de fichier n'est qu'un lien vers cet inode et est appelé "lien dur". Il n'y a aucune différence entre le prénom d'un fichier et tout lien ultérieur. La réponse est donc "oui": un lien dur est un fichier régulier et, en effet, un fichier régulier est un lien dur.

La lscommande vous montrera combien de liens durs il y a vers le fichier.

Par exemple:

seumasmac@comp:~$ echo Hello > /tmp/hello.txt
seumasmac@comp:~$ ls -l /tmp/hello.txt 
-rw-rw-r-- 1 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

Ici, nous avons créé un fichier appelé /tmp/hello.txt. Le 1dans la sortie de ls -lindique qu'il existe 1 lien dur vers ce fichier. Ce lien dur est le nom du fichier lui-même /tmp/hello.txt.

Si nous créons maintenant un autre lien dur vers ce fichier:

seumasmac@comp:~$ ln /tmp/hello.txt /tmp/helloagain.txt
seumasmac@comp:~$ ls -l /tmp/hello*
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/helloagain.txt
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

vous pouvez maintenant voir que les deux noms de fichiers indiquent qu'il y a 2 liens durs vers le fichier. Aucun de ceux-ci n'est le nom de fichier "correct", ils sont tous deux également valides. Nous pouvons voir qu'ils pointent tous les deux vers le même inode (dans ce cas, 5374043):

seumasmac@comp:~$ ls -i /tmp/hello*
5374043 /tmp/helloagain.txt  5374043 /tmp/hello.txt

Il existe une idée fausse commune selon laquelle cela est différent pour les répertoires. J'ai entendu des gens dire que le nombre de liens renvoyés par lsun répertoire est le nombre de sous-répertoires, y compris .et ..qui est incorrect . Ou, au moins, alors qu'il vous donnera le bon numéro, c'est juste pour les mauvaises raisons!

Si nous créons un répertoire et faisons un, ls -ldnous obtenons:

seumasmac@comp:~$ mkdir /tmp/testdir
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 2 seumasmac seumasmac 4096 Oct  4 13:20 /tmp/testdir

Cela montre qu'il existe 2 liens durs vers ce répertoire. Ceux-ci sont:

/tmp/testdir
/tmp/testdir/.

Notez que ce /tmp/testdir/..n'est pas un lien vers ce répertoire, c'est un lien vers /tmp. Et cela vous explique pourquoi fonctionne le "nombre de sous-répertoires". Lorsque nous créons un nouveau sous-répertoire:

seumasmac@comp:~$ mkdir /tmp/testdir/dir2
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 3 seumasmac seumasmac 4096 Oct  4 13:24 /tmp/testdir

vous pouvez maintenant voir qu'il y a 3 liens durs vers le /tmp/testdirrépertoire. Ceux-ci sont:

/tmp/testdir
/tmp/testdir/.
/tmp/testdir/dir2/..

Ainsi, chaque nouveau sous-répertoire augmentera le nombre de liens d'un, en raison de l' ..entrée qu'il contient.

seumasmac
la source
Je comprends le fonctionnement des métadonnées, des inodes et des liaisons physiques. J'avais juste besoin de clarifier si le fichier lié en dur était compté comme un fichier normal. Cela me montre seulement que la réponse est «oui» en raison de la colonne dédiée à cela, ce qui indique implicitement que cela est natif de tous les fichiers. Je suis désolé, mais je vais devoir voter contre ceci :(
M. Minty Fresh
C'est bien, je suis sûr que ce sera des informations utiles pour quelqu'un d'autre.
seumasmac
Édition intéressante avec le système de liens durs dotglob, je n'ai jamais su qu'il faisait ça.
M. Minty Fresh
J'ai clarifié le lien des liens durs == paragraphe des fichiers réguliers.
seumasmac
1
Particulièrement comme la phrase: "Aucun de ceux-ci n'est le nom de fichier" correct ", ils sont tous deux également valides." C'est un ingrédient crucial pour comprendre les liens durs. Très bien écrit.
Wildcard
4

Les liens matériels comptent-ils comme des fichiers normaux?

Les liens matériels comptent pour tout ce à quoi ils sont liés. Vous pouvez créer un lien vers n'importe quoi sur le même système de fichiers.

mkdir test
cd !$

>file
ln -s file sym
mknod pipe p

ln file file2
ln -P sym sym2
ln pipe pipe2

ls -al

# sockets, too:
cat >tsock.c <<\EOD
#include <sys/socket.h>
#include <sys/un.h>
int main(int n, char **a)
{
        struct sockaddr_un test = { AF_UNIX, "socket" };
        int testfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
        bind(testfd,(struct sockaddr *)&test,sizeof test);
}
EOD
make tsock
./tsock

ln socket socket2

ls -al

# even devices if you want:
sudo mknod mytty c 5 0
ln mytty mytty2
sudo chmod 666 mytty

ls -al
# notice permissions are on an object not on the links to it:
echo Hi, Kilroy! >mytty2  

Chaque lien dur vers quoi que ce soit est équivalent, l'objet sous-jacent reste aussi longtemps qu'il y a un lien (modifier: non symbolique) vers lui (même un descripteur de fichier ouvert, pour lequel j'ai une raison embarrassante d'être très reconnaissant).

Le système appliquera des règles sur les liens de répertoire, vous obtenez un lien nommé vers un répertoire et le système ajoute automatiquement son .lien intégré et les ..liens de tous les sous-répertoires (notez que .dans le ls ci-dessus a deux liens) mais c'est une vérification explicite, sur certains modded les utilisateurs privilégiés des systèmes qui promettent de promettre de ne pas faire de boucles peuvent ajouter eux-mêmes de nouveaux liens. Le système de fichiers ne s'en soucie pas, il peut très bien représenter des graphes de répertoires arbitraires, mais personne ne veut les traiter.

Il y a (beaucoup de systèmes de fichiers non-unix) qui ne fonctionnent pas de cette façon, y compris certains qui appellent ce qu'ils proposent en tant que "liens durs" de substitution. OS X a kludged un équivalent sur HFS + (qui ne les a pas nativement) si je me souviens bien, je ne sais pas avec quelle fidélité il préserve la sémantique ici.

jthill
la source
qu'est-ce que ça ./tsockfait de toute façon?
mikeserv
@mikeserv C'est le programme make-a-socket ci-dessus, il dépose juste un lien de socket nommé "socket" dans son répertoire courant.
2015 à 16h43
ok, mais j'aurais peut-être dû clarifier le peu que je connais sur les sockets. Je pense que je comprends assez bien les liens et cela donne donc un nouveau nom à la même socket, non? cela n'a pas de signification particulière pour les prises ou quoi que ce soit, oui? désolé pour mon ignorance.
mikeserv
1
@mikeserv Un socket est une entité purement exécutable. socket()crée un socket réel, bind()lui donne un nom spécifique, connect()connecte un socket que vous avez créé à un socket nommé. Différents types de prises utilisent différents types de noms, par exemple les sockets Internet utilisent des adresses Internet, mais ils ont tous API d'actions ordinaires (y compris read()et write(), il me rend triste que vous ne pouvez pas open()une prise de système de fichiers et que le système d' exploitation ou libc socket()et connect()pour vous) . man 7 socketa plus, tous les protocoles de mise en réseau font pour une page de manuel agitée.
2015 à 5h03
1
@mikeserv Vous voyez, je peux épeler pty et pts, et probablement même ptmx par une bonne journée, mais c'est tout. :-) au moins le noeud 5,0 fonctionne partout où je peux trouver, c'est le type d'appareil de contrôle-tty. Je l'ai eu avec juste ls -l / dev / tty, je suppose que j'ai eu de la chance là-bas.
2015