¿Es bueno hacer que diff compruebe un enlace de enlace simbólico?

8

En Linux uno puede usar el comando diffpara verificar las diferencias de archivos. Lo uso para verificar las diferencias entre dos módulos, ambos copiados /tmp.

Sin embargo, ambos módulos tienen enlaces simbólicos, que pueden no estar apuntando al archivo correcto, ya que los módulos se han copiado en el /tmpdirectorio. Pero esto no importa. Lo que quiero verificar es si los enlaces simbólicos son iguales.

Por ejemplo, en un módulo se lee el enlace simbólico

/home/test/file1

y en el otro el enlace simbólico dice:

/etc/rc.d/whatever

diffahora arroja un error porque, en general, no puede encontrar el archivo. Pero quiero dejar diffdecir: "Oye, esos enlaces simbólicos no son lo mismo", independientemente de si los enlaces apuntan a archivos válidos o no.

Pregunta: ¿Cómo es posible diffhacer eso, es decir, no intentar seguir los enlaces, sino diferir los enlaces en sí?

Alex
fuente

Respuestas:

6

Pruebe GNU diffversión 3.3 o posterior con la --no-dereferenceopción (y presumiblemente la opción --recursive):

diff --recursive --no-dereference tree1root tree2root
Britton Kerin
fuente
¿Podrías desarrollar esto un poco? ¿Quizás dar un ejemplo de cómo podría usarse? Esto tiene el resultado de una respuesta perfectamente buena, pero nos gusta que nuestras respuestas sean un poco más explícitas y detalladas aquí.
terdon
3

Desde la versión 3.3, GNU diff no admite enlaces simbólicos sin referencia, pero luego compara las rutas a las que apuntan.

Instale GNU diffutils> = 3.3 y use la opción '--no-dereference'; No hay una opción corta para eso.

El diagnóstico será silencioso si las rutas son iguales o:

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

si los caminos difieren

Philippe De Muyter
fuente
1

Con herramientas GNU:

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

Estrictamente hablando, eso no puede diferenciar entre un enlace simbólico llamado a aque apunta b -> cy uno a -> bque llama a eso c, sin mencionar los problemas con los nombres de archivo que contienen caracteres de nueva línea, pero eso hace que la salida sea más legible que la más robusta:

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)

Allí, usamos //como separador (que no puede ocurrir de otra manera en la salida de findfor %p) y convertimos los caracteres de nueva línea en caracteres NUL (que no pueden ocurrir en la expansión de %pni %l).

Stéphane Chazelas
fuente
1

Si entiendo correctamente, desea verificar que los enlaces simbólicos apuntan al mismo destino teórico, o que si uno no es un enlace simbólico, el otro archivo enlaza con el mismo archivo. Esto debería hacer lo que quieras:

#!/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
fuente
@StephaneChazelas Ese es mi error, quise usar -m, no -f. ¡Gracias!
Chris Down
Estrictamente hablando, eso no funcionaría si la única diferencia es el número de caracteres de línea nueva en los objetivos de los enlaces simbólicos.
Stéphane Chazelas
Yo tampoco lo usaría -m.
Stéphane Chazelas
@StephaneChazelas ¿Por qué razón? Sin él, los enlaces simbólicos relativos que realmente apuntan al mismo archivo fallarán en esta comparación.
Chris Down
Si /home/test/file1es un enlace simbólico a /etc/rc.d/whatever, o ambos son un enlace simbólico a /, informaría que son lo mismo. Creo que el OP quiere ver la diferencia en la "ruta" almacenada en el enlace simbólico, no si se resuelven en el mismo archivo (para el que tiene [[ a -ef b ]]).
Stéphane Chazelas