Como diff sobre ssh?


175

Como difiro arquivos / pastas entre computadores, desde que a única conectividade disponível seja ssh?


8
Há uma pergunta relativamente semelhante em # 16661: Como posso diferenciar dois servidores RedHat Linux? . A resposta lá, para salvar os cliques, é rsync -ani --delete / root@remotehost:/apenas a resposta completa, que fornece mais detalhes.
Owen Blacker

Muitas respostas aqui, mas qual abordagem é mais rápida?
pl1nk

Respostas:


150

Você pode fazer isso com a substituição do processo do Bash :

 diff foo <(ssh myServer 'cat foo')

Ou, se ambos estiverem em servidores remotos:

diff <(ssh myServer1 'cat foo') <(ssh myServer2 'cat foo')

12
Sim, algo assim, mas para diretórios :)
Alexey Timanovsky

O que quer dizer para os diretórios, sempre poderia substituir gato com ls
Kyle Brandt

27
Eu suspeito que 'para diretórios' significa fazer um recursivo diff
Ian Clelland

9
Descobri que essa técnica não funcionava para mim se meu host remoto exigisse uma senha. O prompt de senha não pareceu funcionar bem com o redirecionamento e não pôde ser concluído com êxito. Se você usar chaves ssh, isso não deve ser um problema.
Adam Franco

2
Esta é uma ótima solução geral para muitos problemas. Em vez de 'cat foo', você pode usar 'find / foo / bar -type f | enquanto lê o arquivo; faça eco "**** $ file"; gato "$ file"; done 'e você terá uma lista dos nomes dos arquivos e do conteúdo dos mesmos.
Paul Engrenagem

106

Finalmente encontrei uma ótima solução: vimdiff

vimdiff /path/to/file scp://remotehost//path/to/file

obrigado a http://linux.spiney.org/remote_diff_with_vim_and_ssh, veja também http://www.vim.org/scripts/script.php?script_id=1075 .


7
E os diretórios? :)
Perlnika

1
Aqui está um exemplo: vimdiff .bash_profile scp: //vaibhavc@10.217.212.97//home/vaibhavc/.bash_profile
vaichidrewar

4
2 barras //após o remotehosté importante. Única barra não vai funcionar
Lee Chee Kiam

2
Se você tem um nome de usuário diferente no host remoto do que o seu host atual, você usariavimdiff /path/to/file scp://username@remotehost//path/to/file
JaredC

como você pode fazer isso com dois hosts remotos com arquivos-chave id_rsa @JaredC?
Manatax

61

Se você quiser apenas ver quais arquivos são diferentes, em vez de comparar os arquivos reais, poderá usar rsync --dry-run


10
rsync -n é a versão curta.
volni

Ótimo - se você precisar usar outra porta, use rsync -e "ssh -p 2222" <SRC> <DST> #
Samoth

16

Aqui está outra receita rápida e suja da linha de comando. Diferente da resposta escolhida, ela funciona dentro de makefiles:

ssh [login]@[host] "cat [remote file]" | diff - "[local file]"

Se minha edição não for concluída: esse método é superior à resposta escolhida porque funciona com makefiles.
22613 Chris Redford

@ Steve Dickinson - o que você quer dizer com "funciona dentro de makefiles"?
Martin Vegter

1
Essa também é uma boa solução se você sofre de alergia ao vim como eu. :) Criei um script bash que compara o mesmo arquivo em dois hosts diferentes, útil ao migrar serviços entre máquinas e comparar arquivos de configuração. Veja gist.github.com/jhqv/dbd59f5838ae8c83f736bfe951bd80ff
Janek

10

Use scp para trazer os arquivos para uma máquina comum e diferenciá-los lá?

Ou, se você quiser apenas saber se os arquivos são diferentes ou não, faça o hash com md5sum em cada máquina.

Você também pode procurar algo como SSHFS , mas não sei o desempenho de um algoritmo como o diff.


2
Uma maneira mais fácil de ver se os arquivos são diferentes ou não é rsync --dry-run.
Gerald Combs

Eu tinha esquecido o SSHFS. Isso funcionou muito bem para mim ...
arod

7

Uma maneira, se for possível no seu sistema, seria simplesmente montar o sistema de arquivos remoto com sshfs .


diff é geralmente uma ação única, como verificar a diferença de configuração. A montagem do sistema de arquivos sempre é possível, mas não é conveniente. Eu seria melhor tar e scp.
Alexey Timanovsky

3

Você pode usar rsyncno modo de execução a seco, conforme sugerido brevemente em outra resposta . Ele lista todos os arquivos que são diferentes.

Para isso, use as rvncopções ( r= recursiva, v= detalhada, n= execução a seco, c= soma de verificação). No rsyncmodo pull ( rsync [OPTION...] [USER@]HOST:SRC... [DEST]), um exemplo é:

rsync -rvnc root@182.18.158.207:/var/www/html/dev/ .

Lembre-se , isso não fornece informações sobre se o arquivo local ou remoto é mais recente. Apenas se eles diferem.


2
  • na sua máquina local, faça uma cópia recursiva do diretório que deseja diferenciar. Por exemplo:

    cp -R dir replica
    
  • use o rsync para replicar o diretório remoto pela cópia local:

     rsync remote:/path/to/dir replica
    
  • use diff para encontrar a diferença entre o diretório local e a réplica local do remoto:

    diff dir replica
    

2

Se você possui sshfs e precisa diferenciar diretórios:

mkdir remote_path
sshfs user@host:/path/ remote_path
diff -r path remote_path

1

Aqui está como eu fiz isso.

Usei o SFTP no servidor remoto e digitei meu nome de usuário / senha quando solicitado. Então eu usei o diretório que foi criado no diretório .gvfs no meu diretório pessoal no comando diff.

diff -r --brief / home / usuário dir / .gvfs / SFTP \ on \ freenas.local / caminho para dir / dir1 / caminho para local dir / dir2


1

Este é um script que pode ajudar a diferenciar a pasta local e a pasta remota .:

 #!/bin/bash

 LOCALFOLDER=/var/www/tee
 REMOTEFOLDER=$(ssh root@111.111.111.1 'ls -lA /hfs/tee'| grep -E '^total' | cut -d " " -f 2 > remotessh.txt)
 COMMAND=$(ls -lA $LOCALFOLDER | grep -E '^total' | cut -d " " -f 2 > localssh.txt)
 REM=$(cat remotessh.txt)
 LOCAL=$(cat localssh.txt)

 echo $LOCAL
 echo $REM

 if [ $REM -eq $LOCAL ]
 then
      echo Directories are the same
 else
      echo Directories are differnt
 fi

 #diff localssh.txt remotessh.txt | grep -E '^total' | cut -d " " -f 2


1

Use sshfs montados no ssh. Não será tão rápido, mas você pode usar todo o seu conjunto de ferramentas que espera que tudo esteja em um sistema de arquivos local. Uma alternativa é o NFS em um túnel feito com "ssh -w" (ou outras comunicações em que ssh não é a limitação).


1

Você também pode tentar generalizar a abordagem criando uma função bash, possivelmente no seu ~ / .bashrc:

myrdiff() { ssh root@"$1" cat "$2" | diff -s - "$2" ; }

invocando-o com uma construção como:

myrdiff vm20-x86-64 /etc/gdm/Init/Default

Invocando diff com -s, isso também informa se os arquivos são idênticos.

Felicidades! Jim

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.