Quente para fazer o diff checar um link simbólico em si?

7

No Linux, pode-se usar o comando diff para verificar diferenças de arquivos. Eu o uso para verificar as diferenças entre dois módulos, ambos copiados para /tmp .

No entanto, ambos os módulos possuem links simbólicos, que podem não estar apontando para o arquivo correto, já que os módulos foram copiados para o diretório /tmp . Mas isso não importa. O que eu quero verificar é se os links simbólicos são os mesmos.

Por exemplo, em um módulo, o link simbólico lê

/home/test/file1

e no outro o link simbólico diz:

/etc/rc.d/whatever

diff agora gera um erro porque - em geral - não consegue encontrar o arquivo. Mas eu quero deixar diff dizer: "Ei, esses links simbólicos não são os mesmos", independentemente de os links apontarem para arquivos válidos ou não.

Pergunta: Como é possível para diff fazer isso, ou seja, não tentando seguir links, mas para diferenciar os próprios links?

    
por Alex 11.11.2013 / 08:24

4 respostas

4

Teste o GNU diff versão 3.3 ou posterior com a opção --no-dereference (e presumivelmente a opção --recursive):

diff --recursive --no-dereference tree1root tree2root
    
por 24.08.2014 / 00:28
2

Desde a versão 3.3, o GNU diff suporta não desreferenciar links simbólicos, mas compara os caminhos para os quais eles apontam.

Instale o GNU diffutils > = 3.3 e use a opção '--no-dereference'; não há uma opção curta para isso.

O diagnóstico será silencioso se os caminhos forem iguais ou:

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

se os caminhos forem diferentes.

    
por 14.01.2015 / 17:54
1

Com ferramentas GNU:

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

Estritamente falando, não é possível diferenciar entre um link simbólico chamado a que aponta para b -> c e um chamado a -> b que aponta para c , sem mencionar os problemas com nomes de arquivos contendo caracteres de nova linha, mas contribui para uma saída mais legível do que a mais robusta:

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

Lá, usamos // como o separador (que não pode ocorrer na saída de find para %p ) e convertemos os caracteres de nova linha em caracteres NUL (o que não pode ocorrer na expansão de %p nem %l ).

    
por 11.11.2013 / 12:10
1

Se eu entendi corretamente, você quer verificar se os links simbólicos apontam para o mesmo destino teórico, ou se um não é um link simbólico, o outro arquivo se vincula ao mesmo arquivo. Isso deve fazer o que você quer:

#!/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
    
por 11.11.2013 / 09:15

Tags