rsync: Un vistazo a este extraordinario comando
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
.
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.
Si C1 quiere enviar el archivo A a C2, ocurre lo siguiente:
- 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.
- Por cada uno de esos bloques C2 calcula dos checksums, uno débil de 32 bits, y uno fuerte de 128 bits (un MD4).
- C2 envía a C1 esos checksums.
- 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.
- 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!