rsync jest zdecydowanie odpowiednim narzędziem do tego zadania. Istnieje, aby utrzymywać synchronizację katalogów i można to zrobić za pomocą sprytnej inteligencji. Na przykład: przesyła tylko delty, gdy tylko jest to możliwe i może pracować w tunelach ssh.
Załóżmy, że masz źródło maszyny, które obsługuje twoją bieżącą wersję drzewa katalogów /my/tree
i ujścia maszyny , które chcesz ściśle z nim synchronizować. Jeśli posiadasz konto ssh na zlewie, możesz, ze źródła użyj rsync w następujący sposób:
rsync -avz --delete -e ssh /my/tree/ remoteuser@sink:/my/tree
Zakłada się, że chcesz /my/tree
dokładnie w tym samym miejscu na zlewie, co masz na źródle . Oczywiście nie musisz trzymać go dokładnie w tym samym miejscu.
Podział wiersza poleceń:
-avz
: tryb archiwizacji, pełne, użyj kompresji podczas przesyłania
--delete
: usuń synchronizowane pliki , których nie ma w źródle
-e ssh
: Użyj ssh jako metody połączenia
Podczas tego połączenia oczywiście poprosimy Cię o podanie hasła. Jeśli chcesz to zrobić w sposób zautomatyzowany, musisz udostępnić niektóre klucze między kontami na komputerach i użyć szyfrowania klucza publiczno-prywatnego, aby nawiązać połączenie ssh.
Aby skonfigurować parę kluczy dla tego rysnc, uruchom następujące polecenie na komputerze źródłowym :
> ssh-keygen -t rsa -b 2048 -f ~/.ssh/my-rsync-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): [press enter here]
Enter same passphrase again: [press enter here]
Your identification has been saved in ~/.ssh/my-rsync-key.
Your public key has been saved in ~/.ssh/my-rsync-key.pub.
The key fingerprint is:
2e:28:d9:ec:85:21:e7:ff:73:df:2e:07:78:f0:d0:a0 root@source
> chmod 600 ~/.ssh/my-rsync-key
Na tej pary kluczy do pracy musimy dodać zawartość ~/.ssh/my-rsync-key.pub
do ~<remoteuser>/.ssh/authorized_keys
pliku na zlew maszyny.
Najpierw skopiuj plik do zlewu :
scp ~/.ssh/my-rsync-key.pub remoteuser@sink:~
Następnie ssh do zlewu i zaimportuj klucz, uruchamiając następujące polecenie jako zdalny użytkownik na komputerze:
> if [ ! -d ~/.ssh ]; then mkdir ~/.ssh ; chmod 700 ~/.ssh ; fi
cd ~/.ssh/
if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi
cat ~/my-rsync-key.pub >> authorized_keys
rm ~/my-rsync-key.pub
Aby uzyskać dodatkowe wskazówki na temat blokowania połączenia ssh między twoim urządzeniem źródłowym a zlewem , polecam zajrzeć na tę stronę .
Na komputerze źródłowym możesz sprawdzić, czy ta konfiguracja działa, uruchamiając:
rsync -avz --dry-run -e "ssh -i ~/.ssh/my-rsync-key" /my/tree/ remoteuser@sink:/my/tree
Spowoduje to wykonanie suchego uruchomienia programu rsync. Jeśli zobaczysz komendę rsync łączącą i porównującą pliki, wiesz, że wszystko zostało poprawnie skonfigurowane.
Teraz potrzebujemy prostego sposobu na wywołanie tego polecenia rsync z pliku konfiguracyjnego LaunchD, jak pokazano w tej pomocnej odpowiedzi na tej stronie . Ponieważ chcesz, aby to wywołanie odbywało się w ciasnej pętli, musisz upewnić się, że nie masz wielu kopii rsync działających w tym samym czasie. Możesz użyć flocka, aby utworzyć muteks, który zapewnia, że skrypt bash jest singleton: tylko jedno jego wystąpienie działa na komputerze na raz. Więc stworzymy następujący skrypt na dysku:
#!/bin/sh
SINK_INSTANCE=remoteuser@sink
DIR=/my/tree
KEY=~/.ssh/my-rsync-key
LOG = ~/my_rsync.log
LOCK = ~/my_rsync.lock
SOURCE=/my/tree
exec 9>${LOCK}
if ! flock -n 9 ; then
echo "Another instance of your rsync is already running";
exit 1
fi
echo "----------" >> ${LOG}
echo `date` >> ${LOG}
rsync -avz --delete -e "ssh -i ${KEY}" \
${SOURCE}/ {SINK_INSTANCE}:${SOURCE} 2>&1 >> ${LOG}
Zapisz to jako ~/my_rsync.sh
.
Ten skrypt zajmie się rsync dla Ciebie. Wszystko, co musisz teraz zrobić, to skonfigurować go za pomocą LaunchD i uruchomić w ciasnej pętli. Postępując zgodnie z instrukcjami z tego miejsca i modyfikując go w celu zaspokojenia naszych potrzeb, utworzymy ~/Library/LaunchAgents/my-rsync.plist
w edytorze tekstu i utworzymy zawartość:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>My Rsync</string>
<key>Program</key>
<string>/bin/sh</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>while sleep 5s; /Users/my/my_rsync.sh; done</string>
</array>
<key>ServiceDescription</key>
<string>Keep /my/tree synchronized with the machine sink</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
To powinno załatwić sprawę.
Obowiązują zwykłe zastrzeżenia: napisałem to z pamięci i nie przetestowałem. Więc nie podążajcie ślepo. Po drodze dokładnie przetestuj. Ilekroć masz wątpliwości, skorzystaj z --dry-run
opcji na rsync. To będzie drukować, co to będzie zrobić bez faktycznie robi nic.