Barres obliques sur les liens symboliques vers les répertoires


8

J'essaie d'émuler le processus de résolution de chemin (voir la page de manuel path_resolution) dans les systèmes de type Unix.

Mon OS est Linux avec GNU coreutils 8.7.

Afin de clarifier la signification de «/» de fin supplémentaire dans la résolution, j'ai fait les choses suivantes dans un shell:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Tout allait bien, car this_is_link est un lien symbolique, et je viens de le supprimer. Mais en essayant:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

Cela a fait écho rm: cannot remove 'this_is_link/': Is a directory

Eh bien, je pensais que le '/' de fin provoquait le suivi du lien symbolique. J'ai donc essayé une autre commande:rmdir this_is_link/

Et un résultat amusant est sorti: rmdir: failed to remove 'this_is_link/': Not a directory

Pas ce à quoi je m'attendais. J'ai donc demandé à mon ami de confirmer si le même résultat pouvait être obtenu sur son système. Il avait une version de coreutils inférieure à la mienne. Et le résultat était incroyable, peu importe rmou rmdir 'this_is_link/', la même erreur Not a directoryse produit .

Et un autre ami vient de l'essayer sur son Mac OS, le résultat est: rm=> 'Est un répertoire', rmdir=> le répertoire est supprimé avec succès, le lien est resté .

Existe-t-il des spécifications sur le comportement exact de la résolution du chemin?


Réponses:


7

La spécification POSIX / Single Unix spécifie qu'un nom de chemin avec une barre oblique de fin doit faire référence à un répertoire (voir définitions de base §4.11 résolution de nom de chemin ). foo/est en fait défini comme équivalent à foo/.(à des fins de résolution de chemin, pas lors de la manipulation des noms de fichiers; basenameet dirnameignorer les barres obliques de fin). La plupart des implémentations respectent cela, mais il y a quelques exceptions.

Cela explique le comportement de rm this_is_link/: c'est équivalent à rm this_is_link/., où l'argument est clairement un répertoire.

rmdir this_is_link/devrait également se référer au répertoire. Ce n'est pas le cas sur votre machine est un bug dans GNU coreutils. OSX se comporte correctement ici.


C'est exactement ce dont j'avais besoin, merci mec!
ymfoi

-1

Ma prise:

  • '' rm link / '' échoue parce que rm regarde le dernier caractère, voit que c'est une barre oblique, donne le diagnostic (pas vraiment correct) que vous avez vu;
  • '' rmdir link / '' échoue bien: le lien n'est pas un répertoire, c'est un lien symbolique
  • '' rm link '' réussira correctement

Soit dit en passant, la résolution de chemin n'a pas grand-chose à voir avec cela, il semble simplement que "rm" coupe un coin plutôt que d'invoquer (correctement) "stat" sur un argument (ce que fait rmdir).

À votre santé.


1
En fait, l'inverse semble être vrai: rmappelle stat (enfin, newfstatat, en fait, avec l' AT_SYMLINK_NOFOLLOWoption) et refuse de poursuivre, alors que rmdir appelle réellement rmdir (2), mais obtient ENOTDIR.
Ansgar Esztermann

@AnsgarEsztermann AT_SYMLINK_NOFOLLOWl'empêchera de suivre le lien symbolique, donc rm devrait supprimer le lien lui-même au lieu d'imprimer "Pas un répertoire" qui ne correspond pas à la circonstance.
ymfoi

À partir d'une brève vérification avec stat (1), la barre oblique de fin remplacera l'option. La sortie de statet stat -Lne diffère que si l'argument est donné sans barre oblique de fin.
Ansgar Esztermann

@AnsgarEsztermann Oh, je vois ... Thx. Qu'en est-il des différents effets sur différents environnements? Des idées?
ymfoi

1
C'est le contraire: sur la machine de ymfoi, rmse comporte correctement et rmdirne l'est pas. La fin /devrait les forcer à traiter leur argument comme un répertoire, selon la norme POSIX. Voir ma réponse pour les références .
Gilles 'SO- arrête d'être méchant'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.