Software para sincronizar dos directorios (local / remoto)

Respuestas:

12

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: transferirá solo deltas siempre que pueda y puede funcionar sobre túneles ssh.

Digamos que tiene una fuente de máquina que aloja su versión en vivo del árbol de directorios /my/treey el sumidero de la máquina que desea mantener en estrecha sincronización con él. Si usted tenía una cuenta ssh en el fregadero que podría, de origen uso rsync de la siguiente manera:

rsync -avz --delete -e ssh /my/tree/ remoteuser@sink:/my/tree

Esto supone que desea /my/treeexactamente en el mismo lugar en el fregadero que lo tiene en la fuente . Por supuesto, no necesita mantenerlo exactamente en el mismo lugar.

Desglosando la línea de comando:

  • -avz: modo de archivo, detallado, usar compresión durante la transferencia
  • --delete: eliminar archivos sincronizados que no están presentes en la fuente
  • -e ssh: Use ssh como método de conexión

Esta llamada, por supuesto, le pedirá su contraseña cuando la haga. Si desea hacer esto de manera automatizada, necesitará compartir algunas claves entre las cuentas en las máquinas y usar el cifrado de clave pública-privada para realizar la conexión ssh.

Para configurar su par de claves para este rysnc, ejecute el siguiente comando en su máquina 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 este par de claves para el trabajo que tenemos que añadir el contenido de ~/.ssh/my-rsync-key.pubal ~<remoteuser>/.ssh/authorized_keysarchivo en el fregadero de la máquina.

Primero copie el archivo en la máquina del fregadero :

scp ~/.ssh/my-rsync-key.pub remoteuser@sink:~

Luego ssh a la máquina de sumidero e importe la clave ejecutando lo siguiente como usuario remoto 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 su fuente y las máquinas de sumidero , le recomiendo que eche un vistazo a esta página .

Desde su máquina 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 que el comando rsync conecta y compara los archivos, sabe que las cosas están configuradas correctamente.

Ahora necesitamos una manera 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 ciclo cerrado, deberá asegurarse de que no se ejecuten varias copias de rsync al mismo tiempo. Puede usar flock para crear un mutex que garantice que un script bash sea singleton: solo se ejecuta una instancia cada 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}

Guarda eso 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 ejecutarlo en un ciclo cerrado. Siguiendo las instrucciones desde aquí y modificándolas para satisfacer nuestras necesidades, crearemos ~/Library/LaunchAgents/my-rsync.plisten un editor de texto y crearemos 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 encargarse de las cosas.

Se aplican las advertencias habituales: escribí esto de memoria y no lo probé. Así que no sigas a ciegas. Prueba cuidadosamente en el camino. Cuando tenga dudas, use la --dry-runopción en rsync. Imprimirá lo que hubiera hecho sin realmente hacer nada.

Ian C.
fuente
2

En lugar de ejecutar rsynccada 5 segundos, puede usar el demonio lsyncd para mirar el árbol de directorios.

Funciona en OS X a través /dev/fsevents, pero no tengo un .debarchivo listo para el complemento . Es un poco geek compilarlo e instalarlo. Hasta que lance la versión 2.0.6 (pronto), aconsejaría usar GIT head, ya que lsyncd 2.0.5 tiene algunos errores conocidos de OS X.

axkibe
fuente
Acabo de lanzar una versión fija de OSX. A diferencia de tener que desperdiciar recursos ejecutando algo cada 5 segundos, aunque es probable que no haya pasado nada, Lsyncd llamará a rsync solo cuando algo haya sucedido.
axkibe
1

rsync sería una gran herramienta para esto, y está integrado en Mac OS. Verificará las diferencias entre dos ubicaciones y luego solo copiará los cambios delta a través de la red. rsync sin ningún indicador adicional hace casi exactamente lo que estás buscando.

La única adición es que necesitaría ejecutarlo cada 5 segundos para verificar los cambios. Puede hacerlo utilizando launchd, con un gran ejemplo ya en este sitio . En este ejemplo, parece que el script se sigue ejecutando, y luego duerme 5 segundos, luego se ejecuta nuevamente.

El problema con ejecutar esto tan a menudo es que la herramienta también tendrá que verificar las diferencias, y si hay tantos cambios en 5 segundos, la sobrecarga para registrar esos cambios y transferirlos puede tomar más de 5 segundos.

jmlumpkin
fuente
0

He estado usando FolderSync (8.99 App store) y realmente me gusta. Buena interfaz de usuario con navegación sincronizada en dos paneles. Le permite guardar un trabajo de sincronización para su reutilización posterior.

jtreser
fuente