Retomar o rsync sobre SSH após uma conexão interrompida?

45

Eu tenho que transferir grandes quantidades de dados (> 80 GB) sobre ssh usando o rsync. Tudo está funcionando bem, mas a conexão DSL de onde os dados de backup são enviados cairá uma vez a cada 24 horas por até 3 minutos (a troca de provedor não é uma opção).

Como é que eu:

  1. Reiniciar automaticamente a transferência quando a conexão for restaurada?

  2. Certifique-se de que não haja acidentalmente dois comandos rsync em execução ao mesmo tempo?

Sathyajith Bhat
fonte
Você não pode verificar o código de retorno? while ./run_script; do echo "Retrying..."; done; echo "Done."Garanta run_scriptretorno 0sobre o sucesso.
Kerrek SB 27/06/11
Possível duplicata de serverfault.com/q/98745 .
tanius
Algumas informações úteis aqui - só quero acrescentar que uma maneira de contornar o problema repetido de solicitação de senha é usar o comando 'sshpass'. Normalmente, isso precisa ser instalado com o apt-get etc.
Rachael Saunders

Respostas:

52

O seguinte deve ser útil:

#!/bin/bash

while [ 1 ]
do
    rsync -avz --partial source dest
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "Rsync failure. Backing off and retrying..."
        sleep 180
    fi
done

Quando a conexão morre, o rsync fecha com um código de saída diferente de zero. Esse script simplesmente continua re-executando o rsync, permitindo que ele continue até que a sincronização seja concluída normalmente.

Peter
fonte
1
Obrigado, estou tentando isso agora ... mas deveria: se ["$?" = "0"] not be: if ["$?" == "0"] (operador de comparação)?
1
Não, no bash "=" está a igualdade de cadeias (uma das muitas coisas que a torna confusa, eu acho!) #
Peter Peter
6
== é o pseudônimo para =: D
bbaja42
8
Ah, bom saber. festa nunca deixará de surpreender / horrorizar-me :-P
Peter
2
Tarde para a festa, no entanto, para a posteridade: A) use: if rsync -avz --partial source dest; então ... B) se você quiser comparar valores integrais, se usar parênteses duplos para expansão aritmética: if (($? = 0)) then;
user18402
7

Isso faz o mesmo que a resposta de Peter, mas oferece ao usuário a opção de qual arquivo remoto ele deseja e onde ele deseja salvá-lo (além de realizar o rsync sobre ssh). Substitua USER e HOST pelo seu nome de usuário e host, respectivamente.

#! / bin / bash
echo -e "Digite o caminho completo do arquivo (escapado):"
caminho read -r
eco "Caminho: $ caminho"
echo -e "Digite o destino:"
read -r dst
eco "Destino: $ dst"
enquanto [1]
Faz
    rsync --progress --partial --append -vz -e ssh "USUÁRIO @ HOST: $ path" $ dst
    se ["$?" = "0"]; então
        eco "rsync concluído normalmente"
        Saída
    outro
        eco "falha do rsync. Tentando novamente em um minuto ..."
        dormir 60
    fi
feito

As opções rsync usadas aqui permitem as estatísticas de progresso durante a transferência, o salvamento de arquivos parciais em caso de falha inesperada e a capacidade de anexar arquivos parcialmente concluídos após a retomada. A opção -v aumenta a verbosidade, a opção -z permite a compactação (boa para uma conexão lenta, mas requer mais energia da CPU nas duas extremidades) e a opção -e nos permite realizar essa transferência pelo ssh (a criptografia sempre é boa).

Nota: Use isso apenas se você tiver o login de chave pública ativado com seu ssh; caso contrário, ele solicitará uma senha quando reiniciar (eliminando todas as funcionalidades do script).

KernelSanders
fonte
1
Esta é a melhor resposta da pergunta original. Também se aplica a uma duplicata com a resposta errada em: serverfault.com/questions/98745/… #
rickfoosusa
5

supervisor daemon (um gerenciador de controle de processo) pode funcionar muito bem após a criação de certificados rsa de ambos os lados, com uma configuração semelhante da seguinte: (/ etc / supervisor / supervisord.conf é o caminho do arquivo de configuração em sistemas baseados em debian)

[program:rsync-remoteserver]
command=rsync -avz --progress [email protected]:/destination /backup-path
stdout_logfile=/out-log-path  
stderr_logfile=/errlogpath
ugurarpaci
fonte
1

A resposta do @ Peter parece ser muito útil, mas para mim era importante usar a --updateopção. Depois que a conexão foi retomada, o --updatersync estava tentando sincronizar tudo desde o início. Com --update, os arquivos que já existem são ignorados.

rsync --partial --update --progress -r [SOURCE] [DESTINATION]

YasiuMaster
fonte
2
--updateignora arquivos que já existem ... Incluindo aqueles que não foram completamente copiados para o destino. Eu acho que vai contra a maioria dos casos de uso.
durum
@durum não é verdade, pelo menos no rsync 3.1.2. após a transferência interrompida, vejo que funciona corretamente no mesmo arquivo. Eu usei rsync sobre ssh, o comando foi rsync --partial --update file1 remotehost:file1. depois de transferir 15% quebrei a transferência (kill -KILL).
filiprem 17/01