Como encontrar o md5sum de arquivos em máquinas remotas fazendo o ssh?

2

Estou executando meu script de shell abaixo em machineC, que obtém o md5sum dos meus arquivos no diretório PRIMARY no próprio machineC.

#!/bin/bash

export PRIMARY=/data01/primary

for entry in "$PRIMARY"/*
do
    local_md5sum=$(/usr/bin/md5sum "$entry" | awk '{print $1}')
    echo $local_md5sum
done

Assim que eu executo o script de shell, ele imprime o md5sum dos meus arquivos em machineC e está funcionando bem.

Agora, o mesmo arquivo para o qual estou calculando o md5sum também pode ser em machineA ou machineB, portanto, preciso fazer ssh em machineA e machineB e fazer o mesmo md5sum no mesmo arquivo e armazená-lo na variável remote_md5sum .

Se o arquivo não estiver lá em machineA, então ele deve estar lá em machineB com certeza e os arquivos estarão nesse diretório em machineA e machineB

/bat/test/data/snapshot/20140918

Então eu tenho abaixo o shell script que estou rodando em machineC e também estou tentando encontrar o md5sum dos arquivos em machineA ou machineB

#!/bin/bash

# folder in machineC
export PRIMARY=/data01/primary

readonly SERVERS=(machineA machineB)
export SERVERS_1=${SERVERS[0]}
export SERVERS_2=${SERVERS[1]}

export FILES_LOCATION=/bat/test/data/snapshot/20140918  

for entry in "$PRIMARY"/*
do
    # find local md5sum on machineC
    local_md5sum=$(/usr/bin/md5sum "$entry" | awk '{print $1}')
    echo $local_md5sum

    # find remote md5sum of the file which will be on machineA or machineB
    remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}' || ssh bullseye@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
    echo "Remote Checksum: $remote_md5sum"

    # now compare local_md5sum and remote_md5sum
done

Mas sempre que executo acima do shell script, meu comando ssh falha e ele não armazena o valor md5sum desse arquivo em remote_md5sum . Há algo de errado nesta sintaxe?

remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}' || ssh user@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
    
por david 22.09.2014 / 23:19

3 respostas

4

Eu modifiquei o seu script e este funciona agora. Eu adicionei alguns comentários dentro do script para torná-lo mais compreensível. Deixe-me saber se você precisar de mais ajuda.

#!/bin/bash

#The export path which we set here.
export PRIMARY=/home/ramesh

#The main for loop execution starts here. 
for entry in "$PRIMARY"/*
do
    #Get the base name of the file which we check in the remote servers.
    #Get just the filenames without the path.
    #I am going to use the filename in the remote server to check. 

    filename=$(basename "$entry")
    echo "File Name: $filename"
    #Calculate the MD5Sum locally.
    local_md5sum=$(md5sum "$entry")
    echo "Local MD5Sum: $local_md5sum"

    #Check if the file exists in server1. 
    #Otherwise I can check in the other server.

    if ssh ramesh@server1 stat /home/ramesh/'$filename' \> /dev/null 2\>\&1 then

        #I have the file in server1 and so I get the md5sum from server1.
        #I store the md5sum inside remote_md5sum variable.
        remote_md5sum=$(ssh ramesh@server1 "cd /home/ramesh/; find -name '$filename'  -exec md5sum {} \;")
    else
        #Now, I know the file is in server2 as it is not present in server1. 
        remote_file=$(ssh ramesh@server2 "cd /home/ramesh/; find -name '$filename'  -exec md5sum {} \;")
    fi
    echo "Remote MD5Sum: $remote_file"
done

Teste

Eu queria testar o script acima para nomes de arquivos com espaços também. Funciona bem e esta é a saída que recebo quando executo o script.

File Name: file1
Local MD5Sum:  39eb72b3e8e174ed20fe66bffdc9944e  /home/ramesh/file1
Remote MD5Sum: b5fc751f836c5430b617bf90a8c4725d  ./file1

File Name: file with spaces
Local MD5Sum:  36707e275264f4ac25254e2bbe5ef041  /home/ramesh/file with spaces
Remote MD5Sum: 36707e275264f4ac25254e2bbe5ef041  ./file with spaces
    
por 22.09.2014 / 23:39
2

Primeiro, você nunca usa sua variável FILES_LOCATION . Isso torna inútil. Segundo, você não pode usar || como no shell.

Tente algo como:

entry="$FILES_LOCATION/$(basename "$entry")"

remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}')
if [ -z $remote_md5sum ] ; then 
    remote_md5sum=$(ssh user@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
fi
    
por 23.09.2014 / 00:45
0

Aqui está uma maneira rápida e fácil de fazer isso (todos os comandos em execução em "machine2" como "user1"):

[user1@machine2]$ cd /home/user1/src

[user1@machine2]$ ssh user1@machine1 "cd src;find . -type f -exec md5sum {} \;" | md5sum --check | grep -v "OK"

Altere os diretórios para corresponder ao seu cenário.

Eu peguei isso em algum lugar na net em 2007. Isso ajuda.

    
por 24.09.2014 / 04:19