Wznów rsync przez SSH po zerwaniu połączenia?

45

Muszę przesyłać duże ilości danych (> 80 GB) przez ssh przy użyciu rsync. Wszystko działa dobrze, ale połączenie DSL, z którego wysyłane są dane kopii zapasowej, będzie przerywane co 24 godziny na maksymalnie 3 minuty (zmiana dostawcy nie jest opcją).

Jak ja:

  1. Czy zrestartować transfer automatycznie, gdy połączenie zostanie ponownie utworzone?

  2. Upewnij się, że przypadkowo nie są uruchomione dwie komendy rsync?

Sathyajith Bhat
źródło
Nie możesz sprawdzić kodu powrotu? while ./run_script; do echo "Retrying..."; done; echo "Done."Upewnij się, że run_scriptwraca 0na sukces.
Kerrek SB
Możliwy duplikat serverfault.com/q/98745 .
tanius
Kilka przydatnych informacji tutaj - chcę tylko dodać, że jednym ze sposobów obejścia powtarzającego się pytania o hasło jest użycie polecenia „sshpass”. Zwykle należy to zainstalować za pomocą apt-get itp.
Rachael Saunders

Odpowiedzi:

53

Pomocne powinny być:

#!/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

Po zakończeniu połączenia rsync zakończy działanie z niezerowym kodem wyjścia. Ten skrypt po prostu ponownie uruchamia rsync, pozwalając mu kontynuować do momentu normalnego zakończenia synchronizacji.

Piotr
źródło
1
Dzięki, próbuję tego teraz ... ale czy to: if ["$?" = „0”] not be: if [„$?” == "0"] (operator porównania)?
1
Nie, w bash "=" oznacza równość łańcuchów (myślę, że jedna z wielu rzeczy sprawia, że ​​jest to mylące!)
Peter
6
== jest pseudonimem =: D
bbaja42
8
Ach, dobrze wiedzieć. bash nigdy nie przestanie mnie zadziwiać / przerażać :-P
Peter
2
Późno na imprezę, ale dla potomności: A) użyj: if rsync -avz - partial source dest; następnie ... B) jeśli chcesz porównać wartości całkowite, jeśli używasz podwójnego nawiasu do interpretacji arytmetycznej: if (($? = 0)) to;
user18402
7

Robi to podobnie jak odpowiedź Petera, ale daje użytkownikowi możliwość wyboru pliku zdalnego i miejsca, w którym chce go zapisać (a także przeprowadzić rsync przez ssh). Zastąp USER i HOST odpowiednio nazwą użytkownika i hostem.

#! / bin / bash
echo -e "Wprowadź pełną ścieżkę do pliku (znak zmiany znaczenia):"
czytaj -r ścieżka
echo „Ścieżka: $ ścieżka”
echo -e „Podaj cel:”
czytaj -r dst
echo „Miejsce docelowe: $ dst”
podczas gdy [1]
zrobić
    rsync --progress --partial --append -vz -e ssh "USER @ HOST: $ path" $ dst
    jeśli [„$?” = „0”]; następnie
        echo „rsync zakończony normalnie”
        wyjście
    jeszcze
        echo „błąd rsync. Ponowna próba za minutę ...”
        spać 60
    fi
gotowy

Użyte tutaj opcje rsync umożliwiają statystyki postępu podczas przesyłania, zapisywanie częściowych plików w przypadku nieoczekiwanego niepowodzenia oraz możliwość dołączania do częściowo ukończonych plików po wznowieniu. Opcja -v zwiększa gadatliwość, opcja -z włącza kompresję (dobre dla wolnego połączenia, ale wymaga większej mocy procesora na obu końcach), a opcja -e umożliwia nam przeprowadzenie tego transferu przez ssh (szyfrowanie jest zawsze dobre).

Uwaga: używaj tego tylko, jeśli masz włączoną funkcję logowania do klucza publicznego za pomocą ssh, w przeciwnym razie poprosi cię o hasło przy ponownym uruchomieniu (zabijając całą funkcjonalność skryptu).

KernelSanders
źródło
1
To najlepsza odpowiedź na pierwotne pytanie. Dotyczy to również duplikatu z błędną odpowiedzią na: serverfault.com/questions/98745/…
rickfoosusa
5

demon supervisora ​​(menedżer kontroli procesu) może działać bardzo dobrze po utworzeniu certyfikatów RSA obu stron, z podobną konfiguracją jak poniżej: (/ etc / supervisor / supervisord.conf to ścieżka do pliku konfiguracyjnego w systemach opartych na Debianie)

[program:rsync-remoteserver]
command=rsync -avz --progress [email protected]:/destination /backup-path
stdout_logfile=/out-log-path  
stderr_logfile=/errlogpath
ugurarpaci
źródło
1

Odpowiedź @ Peter wydaje się bardzo przydatna, ale dla mnie ważne było użycie --updateopcji. Po wznowieniu połączenia, bez --updatersync próbował synchronizować wszystko od samego początku. Za pomocą --updateplików, które już istnieją, są pomijane.

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

YasiuMaster
źródło
2
--updatepomija pliki, które już istnieją ... W tym te, które nie zostały całkowicie skopiowane do celu. Myślę, że jest to sprzeczne z większością przypadków użycia.
durum
@ durum nie jest to prawdą przynajmniej na rsync 3.1.2. po przerwanym przesyłaniu widzę, że działa poprawnie na tym samym pliku. Użyłem rsync nad ssh, polecenie było rsync --partial --update file1 remotehost:file1. po przeniesieniu 15% przerwałem transfer (zabij -KILL).
filiprem