Compara recursivamente dois diretórios com diff -r sem saída em links quebrados

32

Estou usando diff -r a b para comparar recursivamente os diretórios a e b . Muitas vezes, no entanto, existem alguns links quebrados (os mesmos links quebrados nos diretórios a e b e apontando para os mesmos destinos não existentes).

diff em seguida, envia mensagens de erro para esses casos e sai com um código de saída diferente de zero, no entanto, eu gostaria que ele ficasse silencioso e saia com 0, pois os diretórios são os mesmos no meu livro .

Como posso fazer isso?

    
por Marcus Junius Brutus 30.09.2012 / 00:57

3 respostas

19

Para a versão 3.3 ou posterior de diff , você deve usar a opção --no-dereference , conforme descrito na resposta de Pete Harlan .

Infelizmente, as versões mais antigas de diff não suportam ignorar links simbólicos :

Some files are neither directories nor regular files: they are unusual files like symbolic links, device special files, named pipes, and sockets. Currently, diff treats symbolic links like regular files; it treats other special files like regular files if they are specified at the top level, but simply reports their presence when comparing directories. This means that patch cannot represent changes to such files. For example, if you change which file a symbolic link points to, diff outputs the difference between the two files, instead of the change to the symbolic link.

diff should optionally report changes to special files specially, and patch should be extended to understand these extensions.

Se tudo que você quer é verificar um rsync (e presumivelmente consertar o que está faltando), então você poderia simplesmente executar o comando rsync uma segunda vez. Se você não quiser fazer isso, então check-somando o diretório pode ser suficiente.

Se você realmente quer fazer isso com diff , então você pode usar find para pular os links simbólicos, e executar o diff em cada arquivo individualmente. Passe seus diretórios a e b como argumentos:

#!/bin/bash
# Skip files in $1 which are symlinks
for f in 'find $1/* ! -type l'
do
    # Suppress details of differences
    diff -rq $f $2/${f##*/}
done

ou como um verso:

for f in 'find a/* ! -type l';do diff -rq $f b/${f##*/};done

Isso identificará arquivos que diferem em conteúdo ou arquivos que estão em a , mas não em b .

Observe que:

  • Como estamos pulando links simbólicos por completo, isso não notará se os nomes dos links simbólicos não estiverem presentes em b . Se você precisasse disso, precisaria de um segundo passe de localização para identificar todos os links simbólicos e depois verificar explicitamente sua existência em b .
  • Arquivos extras em b não serão identificados, pois a lista é construída a partir do conteúdo de a . Isso provavelmente não é um problema para o cenário rsync .
por 30.09.2012 / 02:20
19

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 igual ou:

Links simbólicos /tmp/noderef/a/symlink e /tmp/noderef/b/symlink diferem

    
por 06.05.2014 / 12:50
6

Você pode usar uma versão mais recente de diff

O diff no GNU diffutils 3.3 inclui uma opção --no-dereference que permite comparar os links simbólicos em vez de seus destinos. Ele informa se eles diferem, fica quieto se eles concordarem e não se importam se estão quebrados.

Eu não sei quando a opção foi adicionada; não está presente em 2.8.1.

    
por 12.03.2014 / 22:05

Tags