rsync: Un vistazo a este extraordinario comando

Publicado por Diego Córdoba en

Hoy veremos los puntos principales de la gran utilidad rsync para copiar/sincronizar archivos tanto locales como remotos mediate SSH.

Hace tiempo que quería escribir alguna breve documentación sobre el comando rsync en GNU/Linux, así que acá va.

Cuando pienso en rsync automáticamente se me viene a la cabeza SSH, y la pregunta: ¿por qué no usar scp en lugar de rsync?

Soy un fanático de ssh, y de scp, uso mucho ese comando para copiar archivos locales a mis servidores remotos vía ssh, y viceversa.

rsync - a fast, versatile, remote (and local) file-copying tool

Un breve tutorial: manos a la obra

Primero lo primero: instalar la utilidad. En general el paquete se llama rsync en los repositorios.

#Debian y derivados:
sudo apt install rsync

#Arch Linux:
sudo pacman -S rsync

#RedHat y derivados:
sudo yum install rsync

Ahora, un punto importante, podemos sincronizar archivos locales desde un directorio a otro, o archivos desde el equipo local hacia el remoto o viceversa. La sintaxis en cada caso:

#Local a Local:
rsync [OPTION]... [SRC]... DEST

#Local a Remoto:
rsync [OPTION]... [SRC]... [USER@]HOST:DEST

#Remoto a Local:
rsync [OPTION]... [USER@]HOST:SRC... [DEST]

No obstante, existe la utilidad rsync, que también puede correr dentro de un túnel seguro SSH, y cuya página de manual define de la siguiente manera:

Donde:

  • OPTION representa las opciones de rsync.
  • SRC: archivo o directorio de origen.
  • DST: archivo o directorio de destino.
  • USER: usuario en el equipo remoto.
  • HOST: nombre o IP del equipo remoto.

Las opciones más comunes podríamos decir que son las siguientes:

  • -a o --archive: modo archivo. Esta opción le dice al rsync que sincronice directorios recursivamente, transfiera dispositivos de bloques y dispositivos especiales, preserve enlaces simbólicos (symlinks), y mantenga tiempos de modificación, grupos, dueño y permisos.
  • -z o --compress: esta opción fuerza a rsync a comprimir los datos durante la transferencia, y mejora el rendimiento si la conexión es lenta.
  • -P o «--partial --progress«: esta opción muestra una barra de progreso durante la transferencia y mantiene los datos parciales transferidos de modo que, en caso de que se pierda la conexión, pueda restablecerse. --partial sirve para almacenar estos datos parciales transferidos, y --progress para mostrar la barra de progreso.
  • --delete: si se activa, rsync eliminará archivos extraños en el destino, archivos que no están presentes en el directorio de origen. Es muy útil para sincronizar dos directorios.
  • -q o --quiet: oculta todos los mensajes que no sean errores.
  • -e o --rsh: esta opción permite elegir una shell remota diferente de la utilizada de manera predeterminada.
  • --exclude: permite excluir los archivos especificados durante la transferencia.
  • --exclude-from: permite excluir los archivos especificados en un archivo de texto. Los nombres de los archivos deben estar separados por salto de línea.
  • -v o --verbose: incrementa la verbosidad, muestra más mensajes por pantalla.

Veamos algunos ejemplos.

Copiando localmente con rsync

Para copiar un archivo desde un directorio a otro podemos utilizar algo similar a esto:

rsync -a /var/www/html/sistema_web /var/www/backup/sistema_web_backup

Esto creará el directorio /var/www/backup/sistema_web_backup como copia del directorio local /var/www/html/sistema_web.

Si el directorio destino no existe, rsync lo crea.

Lo mismo puede realizarse con archivos individuales.

Copiando hacia/desde un equipo remoto con rsync

Supongamos ahora que queremos sincronizar el mismo directorio pero en un equipo distinto. Si el directorio es local y queremos enviarlo a un equipo remoto, podemos usar:

rsync -a /var/www/html/sistema_web usuario@host_remoto:/var/www/backup/sistema_web

Y si el directorio es remoto y queremos «traerlo» a nuestra máquina:

rsync -a usuario@host_remoto:/var/www/backup/sistema_web /var/www/html/sistema_web

En este caso se utilizará el protocolo ssh de manera predeterminada en implementaciones modernas de rsync.

No obstante, si el servicio ssh remoto no se encuentra corriendo en el puerto estándar, o debemos especificar alguna otra opción de conexión, podemos invocar al comando ssh para realizar la conexión utilizando el modificador -e o --rsh de esta manera:

rsync -a -e 'ssh -p 2222' /var/www/html/sistema_web usuario@host_remoto:/var/www/backup/sistema_web

Esto primero establecerá el túnel SSH contra el servidor remoto que está atendiendo en el puerto TCP 2222. Aquí podemos utilizar cualquier opción de configuración de ssh, incluso se tienen en cuenta los archivos de configuración locales del cliente ssh.

Video relacionado en nuestro canal de YouTube

Excluyendo archivos

Supongamos que en el directorio local tenemos los archivos hola.txt y mundo.txt que queremos excluir de la transferencia hacia el equipo remoto (al revés el comando es equivalente).

Podemos excluirlos de la siguiente manera:

rsync -a --exclude=hola.txt --exclude=mundo.txt /var/www/html/sistema_web usuario@host_remoto:/var/www/backup/sistema_web

Si, como este caso, son varios archivos, podemos crear un archivo excluidos.txt con este contenido:

hola.txt
mundo.txt

Y luego referenciarlo en el comando rsync usando la opción --exclude-from:

rsync -a --exclude-from='/ruta/al/excluidos.txt' /var/www/html/sistema_web usuario@host_remoto:/var/www/backup/sistema_web

Diferencias con SCP

A simple vista sabemos una cosa del man: rsync puede copiar archivos localmente, cosa que scp no puede. Bueno, esto no es de mucha ayuda, podemos también copiar archivos locales con cp xD

scp internamente funciona de manera similar al comando cp, con la diferencia que uno de los dos extremos de la copia puede ser remoto vía ssh.

Así, scp lee el archivo de entrada y lo escribe en el destino. Esta lectura se realiza de manera lineal, es decir, lee bit por bit del archivo, y los transmite al destino.

rsync por su parte utiliza un algoritmo especial (lo detallo en la siguiente sección), y con el lleva a cabo algunas optimizaciones. Su uso principal es la sincronización de archivos entre dos destinos (de ahí su nombre), es decir, su función es replicar archivos entre dos destinos, por lo que rsync es más que un comando para transferir datos por la red.

Otra diferencia tiene que ver con la seguridad, pero eso lo detallo en un apartado especial más adelante.

Un vistazo al algoritmo de rsync

Supongamos que tenemos dos computadoras remotas, C1 y C2, y que esas computadoras tienen respectivamente los archivos A y B. Esos archivos, A y B, son similares, es decir, comparten parte de su contenido.

rsync transferencia sincronizacion

Si C1 quiere enviar el archivo A a C2, ocurre lo siguiente:

  1. C2 divide el archivo B en una serie de bloques de tamaño fijo de S bytes. El último bloque puede ser menor que S bytes.
  2. Por cada uno de esos bloques C2 calcula dos checksums, uno débil de 32 bits, y uno fuerte de 128 bits (un MD4).
  3. C2 envía a C1 esos checksums.
  4. C1 busca en A todos los bloques de tamaño S con cualquier offset (no solamente múltiplos de S) que tengan los mismos checksums que un bloque de B.
  5. C1 envía a C2 una secuencia de instrucciones para crear una copia del archivo A. Cada instrucción puede ser una referencia a un bloque de B, o datos que no están presentes en B.

Como resultado de este algoritmo, C2 obtendrá una copia de A, pero solamente se transferirán por la red aquellas partes de A que no están en B, junto con algunos checksums. Estas partes se guardarán en un archivo temporal en el destinatario, para que, luego de finalizada la transferencia, se modifique el archivo destino original con el temporal de manera atómica (+info)

El cálculo de los checksums y la comparación podría parecer un cuello de botella, pero el algoritmo utiliza rolling checksums, lo que le da muy buena eficiencia. Ahí dejo el enlace por si quieren profundizar en la matemática del algoritmo.

Otro dato importante, rsync verifica tamaños y tiempos de modificación de los archivos A y B. Si ambos parámetros coinciden, no se realiza ningún intercambio por la red, supone que el archivo no se ha modificado.

Seguridad en la transmisión

rsync es una utilidad que hace uso de un protocolo predeterminado, denominado también rsync://. Este protocolo es similar a http, es decir, no incorpora seguridad, criptografía del canal ni nada por el estilo, realiza transferencias en texto plano.

scp por su parte siempre realiza sus transferencias sobre un túnel seguro de SSH.

En ese sentido scp es más seguro que rsync, aunque versiones modernas de rsync utilizan ssh por defecto.

No obstante, rsync posee una enorme cantidad de modificadores y opciones, y entre ellas, podemos especificar que la transferencia se realice sobre un túnel SSH al igual que scp.

Por ejemplo, para realizar una transferencia usando rsync sobre SSH, podemos invocarlo con la opción --rsh=ssh como hemos visto antes. Esto le indicará que como shell remota utilice el comando ssh.

Con esto estaremos logrando seguridad en la transmisión via rsync.

Conclusiones: ¿rsync o scp?

Ya conocemos scp y rsync, dos grandes herramientas. Surge la pregunta: ¿cuál debo utilizar?

Eso depende de qué es lo que necesitemos. Por ejemplo, para ejecutar copias de archivos de vez en cuando, donde no necesitemos las optimizaciones provistas por rsync, podemos utilizar scp. scp es un comando con una sintaxis más simple y opciones más sencillas.

Ahora, si queremos transferir archivos de manera recurrente entre computadoras, por ejemplo, en cronjobs, la opción correcta es rsync. rsync en este caso aprovecha sus cualidades de sincronización para reducir la cantidad de datos en las transferencias.

Por otro lado, cuando las transferencias involucren archivos grandes, rsync es la opción indicada. Aquí podemos usar el modificador -P para mostrar el progreso en la transferencia, y además, a diferencia de scp, si se corta la transmisión, lanzando nuevamente el comando retomará desde el punto en que había quedado.


Con esto hemos llegado al final!

Si ya conocían rsync, espero haber sumado algún detalle adicional. Si no lo conocían, los invito a probarlo y familiarizarse con sus opciones, suele resultar una herramienta muy útil para todo sysadmin y/o desarrollador.

Hasta la próxima!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador