Chaud pour faire diff vérifier un lien symbolique lui-même?

8

Sous Linux, on peut utiliser la commande diffpour vérifier les différences de fichiers. Je l'utilise pour vérifier les différences entre deux modules, tous deux copiés sur /tmp.

Cependant, les deux modules ont des liens symboliques, qui peuvent ne pas pointer vers le fichier correct, car les modules ont été copiés dans le /tmprépertoire. Mais cela n'a pas d'importance. Ce que je veux vérifier, c'est si les liens symboliques sont les mêmes.

Par exemple, dans un module, le lien symbolique lit

/home/test/file1

et dans l'autre le lien symbolique se lit comme suit:

/etc/rc.d/whatever

difflance maintenant une erreur car - en général - il ne peut pas trouver le fichier. Mais je veux diffdire: "Hé, ces liens symboliques ne sont pas les mêmes", que les liens pointent vers des fichiers valides ou non.

Question: Comment est-il possible diffde faire cela, c'est-à-dire de ne pas essayer de suivre les liens, mais de différencier les liens eux-mêmes?

Alex
la source

Réponses:

6

Essayez GNU diffversion 3.3 ou ultérieure avec l' --no-dereferenceoption (et probablement l'option --recursive):

diff --recursive --no-dereference tree1root tree2root
Britton Kerin
la source
Pourriez-vous étoffer cela un peu? Peut-être donner un exemple de la façon dont il pourrait être utilisé? Cela a les ingrédients d'une réponse parfaitement bonne, mais nous aimons que nos réponses soient un peu plus explicites et verbeuses ici.
terdon
3

Depuis la version 3.3, GNU diff ne prend pas en charge le déréférencement des liens symboliques, mais compare ensuite les chemins vers lesquels ils pointent.

Installez GNU diffutils> = 3.3 et utilisez l'option '--no-dereference'; il n'y a pas d'option courte pour cela.

Le diagnostic sera silencieux si les chemins sont égaux, ou:

Symbolic links /tmp/noderef/a/symlink and /tmp/noderef/b/symlink differ

si les chemins diffèrent.

Philippe De Muyter
la source
1

Avec les outils GNU:

diff <(cd dir1 && find . -type l -printf '%p -> %l\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p -> %l\n'|sort)

À strictement parler, cela ne peut pas faire la différence entre un lien symbolique appelé aqui pointe vers b -> cet celui appelé a -> bqui pointe vers c, sans parler des problèmes avec les noms de fichiers contenant des caractères de nouvelle ligne, mais cela rend la sortie plus lisible que la plus robuste:

diff <(cd dir1 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort)

Là, nous utilisons //comme séparateur (qui ne peut pas se produire autrement dans la sortie de findfor %p) et convertissons les caractères de nouvelle ligne en caractères NUL (qui ne peuvent pas se produire dans l'expansion de %pnor %l).

Stéphane Chazelas
la source
1

Si je comprends bien, vous voulez vérifier que les liens symboliques pointent vers la même destination théorique, ou que si l'un n'est pas un lien symbolique, l'autre fichier est lié au même fichier. Cela devrait faire ce que vous voulez:

#!/bin/bash

if [[ "$(readlink -m -- "$1")" == "$(readlink -m -- "$2")" ]]; then
    echo "files match"
else
    echo "files don't match"
    exit 1
fi
$ > foo 
$ ln -s foo bar
$ ln -s foo baz
$ ./script bar baz
files match
$ ./script bar foo
files match
$ ln -sf qux bar
$ ./script bar foo
files don't match
Chris Down
la source
@StephaneChazelas C'est mon erreur, je voulais l'utiliser -m, non -f. Merci!
Chris Down
À strictement parler, cela ne fonctionnerait pas si la seule différence était le nombre de caractères de fin de ligne dans les cibles des liens symboliques.
Stéphane Chazelas
Je n'utiliserais pas non -mplus.
Stéphane Chazelas
@StephaneChazelas Pour quelle raison? Sans cela, les liens symboliques relatifs qui pointent vraiment vers le même fichier échoueront à cette comparaison.
Chris Down
Si /home/test/file1est un lien symbolique vers /etc/rc.d/whatever, ou ils sont tous les deux un lien symbolique /, il signale qu'ils sont les mêmes. Je pense que l'OP veut voir la différence dans le "chemin" stocké dans le lien symbolique, pas s'ils se résolvent dans le même fichier (pour lequel vous l'avez [[ a -ef b ]]).
Stéphane Chazelas