Je crée un script shell qui prend un nom de fichier / chemin d'accès à un fichier et détermine si le fichier est un lien symbolique ou un lien dur.
La seule chose est, je ne sais pas comment voir si elles sont un lien dur. J'ai créé 2 fichiers, un lien physique et un lien symbolique, à utiliser comme fichier test. Mais comment déterminer si un fichier est un lien physique ou symbolique dans un script shell?
Aussi, comment pourrais-je trouver la partition de destination d'un lien symbolique? Alors disons que j'ai un fichier qui relie à une partition différente, comment pourrais-je trouver le chemin d'accès à ce fichier original?
shell-script
files
symlink
hard-link
k-rocker
la source
la source
ln /foo/bar/ /foo/bar2
crée unln -s /foo/bar /foo/bar2
lien dur tout en faisant un lien symbolique, que veut-il dire?bar2
etbar
sont les deux liens durs, pointant simplement sur le même inode.bar
etbar2
sont d'égale importance. L'un n'est pas un lien vers l'autre, ce sont les deux liens mais pointent vers le même inode.ln
ne sont pas différents des fichiers normaux.Réponses:
La réponse de Jim explique comment tester un lien symbolique: en utilisant
test
le-L
test de.Mais tester un "lien dur" n’est, à proprement parler, pas ce que vous voulez. Les liens physiques fonctionnent à cause de la manière dont Unix gère les fichiers: chaque fichier est représenté par un seul inode. Ensuite, un seul inode a zéro ou plusieurs noms ou entrées de répertoire ou, techniquement, des liens physiques (ce que vous appelez un "fichier").
Heureusement, la
stat
commande, si elle est disponible, peut vous dire combien de noms un inode a.Donc, vous recherchez quelque chose comme ceci (en supposant ici l'implémentation GNU ou busybox de
stat
):Le
-c '%h'
bit indiquestat
de simplement sortir le nombre de liens durs vers l'inode, c'est-à-dire le nombre de noms du fichier.-gt 1
puis vérifie si c'est plus que 1.Notez que les liens symboliques, comme tous les autres fichiers, peuvent également être liés à plusieurs répertoires afin que vous puissiez avoir plusieurs liens durs vers un seul lien symbolique.
la source
stat -f %l /path/to/file
. Vous pouvez également utilisergstat -c %h /path/to/file
le logiciel si vous avez installé les coreutils GNU sans leurs noms par défaut (avec Homebrew sous OS X).Un exemple:
Les
f1
,f2
et lesf3
entrées du répertoire sont le même fichier (même inode: 10802124, vous remarquerez que le nombre de liens est 3). Ce sont des liens en dur vers le même fichier régulier .s4
ets5
sont également le même fichier (10802384). Ils sont de type symlink , pas réguliers . Ils indiquent un chemin, icis3
. Etant donné ques4
ets5
sont des entrées du même répertoire, ce chemin relatifs3
pointe vers le même fichier (celui avec inod 10802347) pour les deux.Si vous faites un
ls -Ll
, cela demande d'obtenir des informations sur le fichier après la résolution des liens symboliques:Vous constaterez qu'ils résolvent tous le même fichier (10802124).
Vous pouvez vérifier si un fichier est un lien symbolique avec
[ -L file ]
. De même, vous pouvez tester si un fichier est un fichier normal avec[ -f file ]
, mais dans ce cas, la vérification est effectuée après la résolution des liens symboliques.Les liens durs ne sont pas un type de fichier, ils ne sont que des noms différents pour un fichier (de tout type).
la source
Utilisation des opérateurs
-h
et-L
de latest
commande:http://www.mkssoftware.com/docs/man1/test.1.asp
Selon ce fil SO , ils ont le même comportement, mais
-L
est préféré.la source
inode
. De plus, les liens symboliques affichent unl
au début de sals -l
sortie ... Je pense que vous pourrez peut-être regrouper ces règles dans un script, ainsi que le[[ -L file ]]
test permettant de voir si le fichier donné est souple ou matériel .Il y a beaucoup de réponses tout à fait correctes ici, mais je ne pense pas que quiconque se soit réellement attaqué à la perception erronée initiale. La question initiale est fondamentalement "quand je fais un lien symbolique, il est facile de l'identifier après. Mais je ne peux pas trouver comment identifier un lien dur." Et oui, les réponses se résument en gros à «vous ne pouvez pas» et expliquent plus ou moins pourquoi, mais personne ne semble l'avoir reconnu. En réalité, c'est un peu déroutant et étrange.
Si vous lisez tout cela et que vous avez compris ce qui se passe, vous êtes bon. vous n'avez pas besoin de lire mon petit morceau. Si vous êtes toujours confus, continuez.
La réponse vraiment courte est qu'un lien dur n'est pas vraiment un lien, pas un lien symbolique. Il s'agit d'une nouvelle entrée dans la structure de répertoires qui pointe vers le même groupe d'octets que l'entrée de répertoire d'origine. Une fois que vous l'avez créée, elle est tout aussi "réelle" et légitime que la première. Chaque fichier "normal" sur votre lecteur comporte au moins un lien physique; sans cela, vous ne le verriez jamaisrépertoire, et serait incapable de s'y référer ou de l'utiliser. Ainsi, si vous avez un fichier Fred.txt et que vous y associez Wilma.txt et Barney.txt, les trois noms (et entrées de répertoire) font référence au même fichier et ils sont tous également valides. Le système d'exploitation n'a aucun moyen de savoir qu'une des entrées a été créée lorsque vous cliquez sur "Enregistrer" dans votre éditeur de texte et les autres avec la commande "ln".
Le système d'exploitation doit cependant savoir combien d'entrées différentes pointent vers le même fichier. Si vous supprimez Wilma.txt, il n’est pas surprenant que vous ne libériez aucun espace sur votre lecteur. Mais si vous supprimez Fred.txt (le fichier "original"), vous ne libérerez toujours aucun espace sur votre lecteur, car les données sur le lecteur qui s'appelait Fred.txt sont toujours aussi Barney.txt. Ce n'est que lorsque vous supprimez toutes les entrées du répertoire que le système d'exploitation désaffectera l'espace occupé par les données elles-mêmes.
Si Barney.txt avait été un lien symbolique, la suppression de Fred.txt aurait annulé l’espace et Barney.txt serait désormais un lien rompu. De même, si vous déplacez ou renommez un fichier contenant un lien symbolique, vous rompez le lien. Mais vous pouvez déplacer ou renommer un fichier lié en dur sans supprimer les autres entrées de répertoire pointant vers ce fichier / cette donnée, car elles sont toutes des entrées de répertoire qui font référence au même bloc de données sur le lecteur (en utilisant inode # de ces données).
[C'est deux ans plus tard, et ce dernier élément m'a dérouté pendant une minute, alors je pense que je vais clarifier. Si vous tapez "mv ./Wilma.txt ../elsewhere/Betty.txt", il semble que vous déplacez le fichier, mais en réalité vous ne l'êtes pas. En réalité, vous supprimez un élément de campagne de la liste de répertoires de votre répertoire actuel, celui qui indique "le nom" Wilma.txt "est associé aux données pouvant être trouvées à l'aide de inode ######. #, "et ajouter un nouvel élément de ligne à la liste de répertoires du répertoire ../elsewhere qui indique" le nom 'Betty.txt' est associé aux données qui peuvent être trouvées via inode ####### ". C'est pourquoi vous pouvez "déplacer" un fichier de 2 gigaoctets aussi rapidement qu'un fichier de 2 kilo-octets, à condition que vous les déplaciez vers un autre emplacement du même lecteur.]
Étant donné que le système d’exploitation doit savoir combien d’entrées de répertoire différentes pointent vers le même bloc de données, vous pouvez savoir si un fichier a été lié à un fichier particulier, même si vous ne pouvez pas savoir avec certitude si l’entrée de répertoire que vous avez regardons est l'original ou pas. Une façon est la commande "ls", plus précisément "ls -l" (c'est un L minuscule après le tiret)
Pour emprunter un exemple précédent ...
La première lettre est un tiret, donc ce n'est pas un répertoire ou quelque chose d'exotique, c'est un fichier ordinaire. Mais s'il était vraiment ordinaire, ce nombre après la partie rwx-ish serait "1", comme dans "il y a une entrée de répertoire pointant vers ce bloc de données". Mais cela fait partie d'une démonstration de liens durs, donc on dit "3".
Notez que cela peut éventuellement conduire à un comportement étrange et mystérieux (si vous ne vous êtes pas entouré de liens durs, c'est-à-dire). Si vous ouvrez Fred.txt dans votre éditeur de texte et apportez des modifications, verrez-vous les mêmes modifications dans Wilma.txt et Barney.txt? Peut être. Probablement. Si votre éditeur de texte enregistre les modifications en ouvrant le fichier d'origine et en les écrivant, alors oui, les trois noms seront toujours dirigés vers le même texte (récemment modifié). Mais si votre éditeur de texte crée un nouveau fichier (Fred-new-temp.txt), y écrit la version modifiée, supprime Fred.txt, puis renomme Fred-new-temp.txt en Fred.txt. Wilma et Barney toujours être pointé vers la version originale, pas la nouvelle version modifiée. Si vous ne comprenez pas les liens physiques, cela pourrait vous rendre légèrement fou. :) [D'accord, je ne connais personnellement aucunles éditeurs de texte qui feraient le nouveau fichier / renommer, mais je connais de nombreux autres programmes qui font exactement cela, alors restez vigilants.]
Une dernière remarque: une des choses que fsck (vérification du système de fichiers) recherche, c’est s’il existe des blocs de données sur votre lecteur qui d’une manière ou d’une autre ne sont plus référencés par aucune entrée de répertoire. Parfois, quelque chose ne va pas, et la seule entrée de répertoire qui pointe vers un inode est supprimée, mais l’espace disque lui-même n’est pas marqué comme "disponible". Ainsi, l'une des tâches de fsck consiste à faire correspondre tout l'espace alloué avec toutes les entrées de répertoire pour s'assurer qu'il n'y a pas de fichiers non référencés. S'il en trouve, il crée de nouvelles entrées dans le répertoire et les met dans "lost + found".
la source
vous pouvez utiliser
readlink FILE; echo $?
. Cela retourne 1 lorsqu'il s'agit d'un lien physique et 0 lorsqu'il s'agit d'un lien symbolique.Dans la page de manuel: "Lorsqu'il est appelé en tant que readlink, seule la cible du lien symbolique est imprimée. Si l'argument donné n'est pas un lien symbolique, readlink n'imprimera rien et sortira avec une erreur."
la source