rsync es definitivamente la herramienta adecuada para este trabajo. Existe para mantener los directorios sincronizados y puede hacerlo con un poco de inteligencia. Por ejemplo: solo transferirá deltas siempre que pueda y puede funcionar a través de túneles ssh.
Supongamos que tiene la fuente de la máquina que aloja su versión en vivo del árbol de directorios /my/tree
y la pila de la máquina que desea mantener en estrecha sincronización con ella. Si tenía una cuenta ssh en sink , desde source puede usar rsync de la siguiente manera:
rsync -avz --delete -e ssh /my/tree/ remoteuser@sink:/my/tree
Esto supone que quieres /my/tree
en el mismo lugar en sink tal como lo tienes en source . Por supuesto, no es necesario mantenerlo en el mismo lugar.
Desglosando la línea de comando:
-
-avz
: modo de archivo, detallado, uso de compresión durante la transferencia
-
--delete
: eliminar archivos en sync que no están presentes en source
-
-e ssh
: use ssh como método de conexión
Esta llamada, por supuesto, le pedirá su contraseña cuando la haga. Si quiere hacer esto de manera automatizada, tendrá que compartir algunas claves entre las cuentas de las máquinas y usar el cifrado de claves públicas y privadas para realizar la conexión ssh.
Para configurar su par de claves para este rysnc, ejecute el siguiente comando en su fuente :
> 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
Para que este par de llaves funcione, necesitamos agregar el contenido de ~/.ssh/my-rsync-key.pub
al archivo ~<remoteuser>/.ssh/authorized_keys
en la máquina sink .
Primero copia el archivo en la máquina sink :
scp ~/.ssh/my-rsync-key.pub remoteuser@sink:~
Luego ssh a la máquina sink e importe la clave ejecutando lo siguiente como remoteuser en la máquina:
> 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
Para obtener consejos adicionales sobre cómo bloquear la conexión ssh entre las máquinas source y sink , recomiendo echar un vistazo a esta página .
Desde su fuente , puede probar que esta configuración funciona ejecutando:
rsync -avz --dry-run -e "ssh -i ~/.ssh/my-rsync-key" /my/tree/ remoteuser@sink:/my/tree
Eso hará una ejecución en seco de un rsync. Si ve el comando rsync conectando y comparando los archivos que sabe, las cosas están configuradas correctamente.
Ahora necesitamos una forma fácil de llamar a este comando rsync desde un archivo de configuración de LaunchD como se muestra en esta útil respuesta en este sitio . Dado que desea que esta llamada se realice en un circuito cerrado, deberá asegurarse de que no se estén ejecutando varias copias de rsync al mismo tiempo. Puede usar flock para crear un mutex que garantice que un script bash sea único: solo una instancia de cada una se ejecuta en Una vez en una máquina. Así que vamos a crear el siguiente script en el disco:
#!/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}
Guárdalo como ~/my_rsync.sh
.
Ese script se encargará de hacer el rsync por ti. Todo lo que necesita hacer ahora es configurarlo a través de LaunchD y hacer que se ejecute en un circuito cerrado. Siguiendo las instrucciones de aquí y modificándolas para satisfacer nuestras necesidades, vamos a crear ~/Library/LaunchAgents/my-rsync.plist
en un editor de texto y hacer los contenidos:
<?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>
Eso debería hacerse cargo de las cosas.
Se aplican las advertencias habituales: escribí esto de memoria y no lo probé. Así que no sigas ciegamente. Prueba cuidadosamente en el camino. Cuando tenga dudas, use la opción --dry-run
en rsync. Imprimirá lo que habría hecho sin hacer nada.