Quente para fazer diff verificar um link de link simbólico em si?

8

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

No entanto, os dois módulos possuem links simbólicos, que podem não estar apontando para o arquivo correto, pois os módulos foram copiados para o /tmpdiretório 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

diffagora gera um erro porque - em geral - ele não consegue encontrar o arquivo. Mas quero diffdizer: "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 difffazer isso, ou seja, não tentando seguir os links, mas diferenciá- los ?

Alex
fonte

Respostas:

6

Experimente o GNU diffversão 3.3 ou posterior com a --no-dereferenceopção (e presumivelmente a opção --recursive):

diff --recursive --no-dereference tree1root tree2root
Britton Kerin
fonte
Você poderia explicar isso um pouco? Talvez dê um exemplo de como ele poderia ser usado? Isso tem como resultado uma resposta perfeitamente boa, mas gostamos que nossas respostas sejam um pouco mais explícitas e detalhadas aqui.
terdon
3

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

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

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

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

se os caminhos diferirem.

Philippe De Muyter
fonte
1

Com as 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, isso não pode diferenciar entre um link simbólico chamado aque aponta para b -> ce um chamado a -> bque aponta para c, para não mencionar os problemas com nomes de arquivos contendo caracteres de nova linha, mas isso gera uma saída mais legível do que a mais 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)

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

Stéphane Chazelas
fonte
1

Se bem entendi, você deseja 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 é vinculado ao mesmo arquivo. Isso deve fazer o que você deseja:

#!/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
fonte
@StephaneChazelas Esse é o meu erro, eu pretendia usar -m, não -f. Obrigado!
Chris Baixo
Estritamente falando, isso não funcionaria se a única diferença fosse o número de caracteres de nova linha à direita nos destinos dos links simbólicos.
Stéphane Chazelas 11/11
Eu também não usaria -m.
Stéphane Chazelas 11/11
@StephaneChazelas Por que motivo? Sem ele, links simbólicos relativos que realmente apontam para o mesmo arquivo falharão nessa comparação.
Chris Baixo
Se /home/test/file1é um link simbólico para /etc/rc.d/whatever, ou ambos são um link simbólico /, informa que são os mesmos. Eu acho que o OP quer ver a diferença no "caminho" armazenado no link simbólico, não se eles resolverem o mesmo arquivo (para o qual você possui [[ a -ef b ]]).
Stéphane Chazelas 11/11