27 Apr 2009

rsync autoresume

Jakiś czas temu byłem zmuszony pobrać dużo danych z serwera który systematycznie co 1GB zrywał połączenie a danych było sporo bo 15GB. Jedną z możliwości ich pobrania było połączenie się programem rsync. Jako, że zależało mi żeby pobrać je szybko, napisałem skrypt automatyzujący wznawianie transferów (wersja którą publikuje jest po drobnych poprawkach). Użycie jest bardzo intuicyjne, najpierw trzeba skrypt zrobić wykonywalnym:
chmod +x rsync2succ.sh
a następnie uruchomić np któreś z poniższych poleceń
  • Powoduje skopiowanie katalogu /sciezka/do/danych z serwera "serwer" do katalogu z którego wywołany jest skrypt
    ./rsync2succ.sh serwer:/sciezka/do/danych/ .
  • Robi to samo co wyżej, jednak nakazuje programowi rsync użyć maksymalnie 100kB/s
    ./rsync2succ.sh --bwlimit-rate 100 serwer:/sciezka/do/danych/ .

Notatki

  • Do skryptu można podać parametry do polecenie rsync (to co dostaje skrypt jest „przeklejane” niemalże bezpośrednio do wywołania komendy rsync)
  • Jako, że ja często zapominam co się dzieje jeśli wpiszę o jeden ukośnik za dużo (pobierana jest zawartość katalogu a nie cały katalog) zrobiłem sobie odcinanie ostatniego znaku /.
  • Mam nadzieję, że skrypt działa poprawnie - bo ja jakoś specjalnie mocno go nie testowałem.
  • Jeśli się np. nie uruchamia - upewnij się, że nie masz w źródle znaków UTF-8 (czasami blogger potrafi zamienić znaki komentarzy na jakieś inne - ale wyglądające tak samo)

rsync2succ.sh - źródło

#!/bin/bash

# Programy wykorzystywane w tym skrypcie.
RSYNC=`which rsync`
DATE=`which date`
SLEEP=`which sleep`
RM=`which rm`
MAXTRIES=2

# Gdzie idzie wyjscie
LOGFILE=log.txt

# pozwalamy tylko na dostep do programow powyzej
unset PATH

# Obsluga sygnalow - sluzy do zabicia dlugo dzialajacego procesu.
trap 'kill $$ ; exit 1' SIGINT

# Obsluga logowania
# jesli byla by koniecznosc umieszczenia informacji w logu systemowym
# nalezy skorzystac z programu logger (/usr/bin/logger)
function log {
 echo `$DATE "+%F %k:%M:%S"`" "$@ >>$LOGFILE
}

function rsync {
 log "starting rsync with params: "$@
 $RSYNC $@
}

## MAIN:
if [ $# -lt 2 ] ; then
 log "no parameters to rsync passed"
 log "at least two parameters must be set"
 exit 1
fi

# filtruj paramatry
for PARAM in $@ ; do 
 # usun znak / z konca argumentu i dodaj go do parametrow
 ARGV=( "${ARGV[@]}" ${PARAM%/} )
done

# usun plik log jesli istnieje
if [ -f $LOGFILE ] ; then
 $RM $LOGFILE
fi

STATUS=1
TRIES=1
while [ $STATUS -ne 0 ] ; do 
 rsync -avzP ${ARGV[@]}
 STATUS=$?

 if [ $STATUS -ne 0 ] ; then
  # wystapil blad przed powtorna proba czekamy 10 sekund
  log "rsync failed with status $STATUS - restarting"
  $SLEEP 10
  if [ $TRIES -ge $MAXTRIES ] ; then
   log "Maximum tries reached ($MAXTRIES) exiting"
   exit 1
  fi
  TRIES=$((TRIES+1))
 else
  log "rsync command completed succesfully"
 fi
done
ps: jeśli chciałbyś się nauczyć pisać w Bashu to zapraszam na moje wiki, natomiast jeśli znasz już ten język a chciałbyś coś o nim napisać - to skontaktuj się ze mną - np. poprzez komentarze.

No comments:

Post a Comment