Resolviendo rsync

rsync es un comando que permite copiar sólo las diferencias de un directorio a otro. Evitando copiar otra vez archivos y directorios que no han cambiado, es útil para hacer más eficiente la sincronización de archivos de un punto a otro de la red. En mi caso, para subir a producción los proyectos que desarrollo en mi computadora local.

Hasta ahora
Lo que venía haciendo era comprimir el directorio, pasarlo por ftp al destino, donde lo descomprimía. En The rsync algorithm: The problem dicen que usualmente eso solamente permite ganar un factor entre 2 y 4.

En Windows
Parte del tiempo la paso en Linux y otra parte (por ahora la mayor) la paso en Windows 7. En Linux, rsync suele estar disponible por default. En Windows, hay que instalarlo. Yo instalé cwrsync, que es libre y provee un comando rsync compatible con el original, para usar en consola.

Luego de instalarlo, revise que la carpeta de cwrsync estuviera en el PATH (Panel de Control, Sistema y seguridad, Sistema, Configuración avanzada del sistema, Variables de entorno, Variables del sistema, PATH). Tuve que hacerlo manualmente.

Problema con Git
Puede ser que, al usar rsync le aparezca un mensaje de error como este:

rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [Receive
r=3.0.7]

Tardé varias horas en encontrar aquí que podía deberse a que Git provee una versión de un ejecutable que cwrsync está tomando en lugar del que debería ser. Para solucionarlo, basta con ir al PATH y colocar al directorio de Git después del directorio de cwrsync. Por ejemplo, en mi caso:

Antes:
C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%JAVA_HOME%\bin;C:\bin\dev\xampp\php;C:\bin\system\gnuwin;C:\bin\dev\drush;C:\Program Files (x86)\Graphics\Graphviz2.26.3\bin;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Python26;C:\Program Files (x86)\Dev\Git\cmd;C:\Program Files (x86)\Dev\Git\bin;C:\Program Files (x86)\cwRsync\bin

Después:
C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%JAVA_HOME%\bin;C:\bin\dev\xampp\php;C:\bin\system\gnuwin;C:\bin\dev\drush;C:\Program Files (x86)\Graphics\Graphviz2.26.3\bin;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Python26;C:\Program Files (x86)\cwRsync\bin;C:\Program Files (x86)\Dev\Git\cmd;C:\Program Files (x86)\Dev\Git\bin

Sin embargo, ahora es Git el que muestra un mensaje de error cuando se ejecuta (aunque, al parecer, realiza bien la acción de todos modos).

Formato de parámetro incorrecto: activa:

Bueno, al menos sabemos la causa y se puede hacer que el PATH sea el adecuado ara git en una consola, y para rsync en otra. Por el momento, hasta hallar una mejor solución a esto.

Probando localmente
Personalmente, puede ser difícil encontrar ejemplos simples que nos ayuden a empezar con rsync. Después de andar medio perdido en el tema, me encaminó este artículo.

Una prueba sencilla es:

rsync -a origen destino

Esto copia el directorio origen dentro de destino.

rsync -a origen/. destino

Esto copia el contenido del directorio origen dentro de destino.

-a es la forma simple de -rlptgoD (no -H) y se supone que funciona bien para el caso usual, que es el de hacer backups de origen en destino.

Hay varias opciones disponibles para el comando.
Se recomienda usar -v para el verbose (más información de lo que está haciendo el comando, se puede colocar -v, -vv, -vvv, etc, según cuánto detalle se desea).
--delete permite que se eliminen del destino aquellas cosas que ya no están en el origen. Usarlo con cautela.

Algo que noté con --delete es que no es lo mismo hacer

rsync --delete -a origen/* destino

que

rsync --delete -a origen/. destino

En el primer caso, usando *, no se produce la eliminación. En el segundo caso, usando ., sí funciona como se espera.

Destino remoto
Lo que deseo es copiar un directorio a un servidor remoto.

Esto se puede hacer con:

rsync -a origen/. username@hostname:path/destino

rsync intentará hacer la copia usando SSH, pidiendo la contraseña.

Hay un modo de configurar ssh para que la autentificación la haga con llaves, pero no he logrado que me funcione hasta el momento.

Algunas opciones recomendadas para el comando usado para copias remotas es:
--progress, que permite ver el avance de la operación
-z, que permite usar un viaje comprimido de lo que se copia
-e ssh, que permite indicar explícitamente que se usa ssh

De ese modo, el comando para sincronizar dos directorios (incluyendo eliminaciones) se vuelve algo como:

rsync --progress --delete -avze ssh origen/. username@hostname:path/destino

Siguientes pasos
  • Que ssh use llaves, para no tener que estar digitando la contraseña a cada rato.
  • Usar drush rsync.
Referencias

Comentarios

Entradas populares de este blog

Mostrando imágenes grandes con Zoomify

Debug con Xdebug y Aptana (y Notepad++)

CSS3 para mejorar el breadcrumb de un tema Zen