jueves, 28 de septiembre de 2017

Archivado y Copias de Seguridad,

Una de las tareas primarias de un administrador de sistemas es mantener la seguridad de los datos del sistema. Una forma de hacerlo es realizando copias de seguridad periódicas de los archivos del sistema. Incluso si no eres el administrador del sistema, a menudo es útil hacer copias de las cosas y mover grandes colecciones de archivos de un lugar a otro y de un dispositivo a otro.

En este capítulo, veremos varios de los programas comunes usados para manejar colecciones de archivos. Están los archivos de compresión de archivos:

  • gzip – Comprime y descomprime archivos
  • bzip2 – Un compresor ordenado por bloques

Los programas de archivado:
  • tar – Utilidad de archivado en cinta
  • zip – Empaqueta y comprime archivos
Y el programa de sincronización de archivos:
  • rsync – Sincronización de archivos y directorios remotos
Comprimiendo archivos

A lo largo de la historia de la informática, ha existido una lucha por almacenar la mayor cantidad de datos posible en el mínimo espacio disponible, ya sea espacio en memoria, dispositivos de almacenamiento o ancho de banda. Muchos de los servicios de datos que hoy consideramos normales como reproductores de música portátiles, televisiones de alta definición o Internet de banda ancha, deben su existencia a las eficaces técnicas de compresión de datos.

La compresión de datos es el proceso de remover la redundancia de los datos. Consideremos un ejemplo imaginario. Digamos que tenemos una foto completamente negra con una dimensiones de 100 por 100 píxeles. En términos de almacenamiento de datos (asumiendo 24 bits, o 3 bytes por píxel), la imagen ocuparía 30.000 bytes de almacenamientos:

100 * 100 * 3 = 30.000

Una imagen que es toda de un color contiene datos completamente redundantes. Si fuéramos listos, podríamos codificar los datos de tal forma que simplemente describiría el hecho de que tenemos un bloque de 10.000 píxeles negros. Así que, en lugar de almacenar un bloque de datos que contenga 30.000 ceros (el negro se representa normalmente en archivos de imagen como cero), podríamos comprimir los datos al número 10.000, seguido de un cero para representar nuestros datos. Éste sistema de compresión de datos se llama run-length enconding y es una de las técnicas de compresión más rudimentarias. Las técnicas de hoy son mucho más avanzadas y complejas pero el objetivo básico sigue siendo el mismo, librarse de los datos redundantes.

Los algoritmos de compresión (las técnicas matemáticas usada para llevar a cabo la compresión) se clasifican en dos categorías, lossless (sin pérdida) y lossy (con pérdida). La compresión sin pérdida mantiene todos los datos contenidos en el original. Ésto significa que cuando un archivo es restaurado de una versión comprimida, el archivo restaurado es exactamente el mismo que la versión original sin comprimir. La compresión con pérdida, por otra parte, elimina datos al realizar la compresión, para permitir que se aplique una mayor compresión. Cuando se restaura un archivo con pérdida, no coincide con la versión original; en su lugar, es una aproximación muy parecida. Ejemplos de compresión con pérdida son JPG (para imágenes) y MP3 (para música). En este tema, veremos sólo la compresión sin pérdida, ya que la mayoría de los datos de un ordenador no pueden tolerar ninguna pérdida de datos.

gzip

El programa gzip se usa para comprimir uno o más archivos. Cuando lo ejecutamos, reemplaza el archivo original por una versión comprimida del original. El programa correspondiente gunzip se usa para restaurar archivos comprimidos a su original forma descomprimida. Aquí tenemos un ejemplo:

 [me@linuxbox ~]$ ls -l /etc > foo.txt
 [me@linuxbox ~]$ ls -l foo.*
 -rw-r--r-- 1 me me 15738 2008-10-14 07:15 foo.txt
 [me@linuxbox ~]$ gzip foo.txt
 [me@linuxbox ~]$ ls -l foo.*
 -rw-r--r-- 1 me me 3230 2008-10-14 07:15 foo.txt.gz
 [me@linuxbox ~]$ gunzip foo.txt
 [me@linuxbox ~]$ ls -l foo.*
 -rw-r--r-- 1 me me 15738 2008-10-14 07:15 foo.txt

En este ejemplo, creamos un archivo de texto llamado foo.txt desde un listado de directorio. A continuación, ejecutamos gzip, que reemplaza el archivo original con una versión comprimida llamada foo.txt.gz. En el listado de directorio de foo.*, vemos que el archivo original ha sido reemplazado con la versión comprimida, y la versión comprimida tiene más o menos la quinta parte del tamaño de la original. Podemos ver también que el archivo comprimido tiene los mismos permisos y datos de tiempo que el original.

A continuación, ejecutamos el programa gunzip para descomprimir el archivo. Tras ello, podemos ver que la versión comprimida del archivo ha sido reemplazada por la original, de nuevo con los permisos y datos de tiempos conservados.

gzip tiene muchas opciones. Aquí tenemos unas pocas:

Opciones de gzip

-c Escribe la salida en la salida estándar y mantiene los archivos originales. También puede especificarse con –-stdout y –-to-stdout.


-d Descomprime. Hace que gzip actúe como gunzip. También puede indicarse con –-dcompress o –-uncompress.

-f Fuerza la compresión incluso si ya existe una versión comprimida del archivo original. También puede indicarse con --force. 

-h Muestra información de uso. También puede especificarse con --help.

-l Lista las estadísticas de compresión para cada archivo comprimido. También puede especificarse con --list.

-r Si uno o más argumentos de la línea de comandos son directorios, recursivamente comprime los archivos incluidos en ellos. También podría especificarse con --recursive.

-t Prueba la integridad de un archivo comprimido. También podría especificarse con --test.

-v Muestra mensajes mientras comprime. También puede indicarse con --verbose.

-number Establece la cantidad de compresión. number es un entero en el rango entre 1 (más rápido, menos comprimido) y 9 (más lento, más comprimido). Los valores 1 y 9 también pueden expresarse como --fast y --best, respectivamente. El valor por defecto es 6.

Volviendo a nuestro ejemplo anterior:

 [me@linuxbox ~]$ gzip foo.txt
 [me@linuxbox ~]$ gzip -tv foo.txt.gz
 foo.txt.gz: OK
 [me@linuxbox ~]$ gzip -d foo.txt.gz

Aquí, hemos reemplazado el archivo foo.txt con una versión comprimida llamada foo.txt.gz. A continuación, hemos probado la integridad de la versión comprimida, usando las opciones -t y -v. Finalmente hemos descomprimido el archivo de vuelta a su forma original.

gzip también puede usarse de formas interesantes vía entrada y salida estándar:

 [me@linuxbox ~]$ ls -l /etc | gzip >
 foo.txt.gz

Este comando crea una versión comprimida de un listado de directorio.

El programa gunzip, que descomprime archivos gzip, asume que los nombres de archivo terminan con la extensión .gz, así que no es necesario especificarla, siempre que el nombre especificado no entre en conflicto con un archivo descomprimido existente.

 [me@linuxbox ~]$ gunzip foo.txt

Si nuestro objetivo fuera sólo ver el contenido de un archivo de texto comprimido, podríamos hacer ésto:

 [me@linuxbox ~]$ gunzip -c foo.txt | less


Alternativamente, hay un programa proporcionado con gzip, llamado zcat, que es equivalente a gunzip con la opción -c. Puede usarse como el comando cat en archivos comprimidos con gzip:

 [me@linuxbox ~]$ zcat foo.txt.gz | less

Consejo: Hay un programa zless también. Realiza la misma función que el pipeline anterior.

bzip2

El programa bzip2, de Julian Seward, es similar a gzip, pero usa un algoritmo de compresión diferente que consigue niveles de compresión más altos a costa de la velocidad de compresión. En la mayoría de los aspectos, funciona de la misma forma que gzip. Un archivo comprimido con bzip2 es marcado con la extensión .bz2:

 [me@linuxbox ~]$ ls -l /etc > foo.txt
 [me@linuxbox ~]$ ls -l foo.txt
 -rw-r--r-- 1 me me 15738 2008-10-17 13:51 foo.txt
 [me@linuxbox ~]$ bzip2 foo.txt
 [me@linuxbox ~]$ ls -l foo.txt.bz2
 -rw-r--r-- 1 me me 2792 2008-10-17 13:51 foo.txt.bz2
 [me@linuxbox ~]$ bunzip2 foo.txt.bz2


Como podemos ver, bzip2 puede usarse de la misma forma que gzip. Todas las opciones (excepto -r) que vimos para gzip también son soportadas en bzip2. Fíjate, sin embargo, que la opción del nivel de compresión (-number) tiene un significado algo diferente para bzip2. bzip2 viene con bunzip2 y bzcat para descomprimir los archivos.

bzip2 también viene con el programa bzip2recover, que tratará de recuperar archivos .bz2 dañados.


No seas un compresor compulsivo

Ocasionalmente veo gente tratando de comprimir un archivo, que ya ha sido comprimido con un algoritmo de compresión efectivo, haciendo algo así:

 $ gzip picture.jpg

No lo hagas. ¡Probablemente sólo estarás malgastando tiempo y espacio! Si aplicas compresión a un archivo que ya ha sido comprimido, acabarás obteniendo un archivo más grande en realidad. Ésto es porque todas las técnicas de compresión incluyen un encabezado que se añade al archivo para describir la compresión. Si tratas de comprimir un archivo que ya no contiene información redundante, la compresión no proporcionará ningún ahorro para compensar el encabezado adicional.


Empaquetando archivos

Una tarea de gestión de archivos que se usa a menudo junto con la compresión es el empaquetado. Empaquetar es el proceso de recoger muchos archivos y empaquetarlos juntos en un gran archivo único. El empaquetado a menudo se hace como parte de los sistemas de copia de seguridad. También se usa cuando se mueven datos antiguos de un sistema a algún tipo de almacenamiento de largo plazo.


tar

En el mundo del software como-Unix, el programa tar es la herramienta clásica para empaquetar. Su nombre, abreviatura de tape archive, revela sus raíces como una herramienta para hacer copias de seguridad en cinta. Mientras que aún se usa para su tarea tradicional, está igualmente adaptada en otros dispositivos de almacenamiento.

A menudo vemos nombres de archivo que terminan con la extensión .tar o .tgz, que indican un paquete tar "plano" y un paquete comprimido con gzip, respectivamente. Un paquete tar puede consistir en un grupo de archivos separados, una o más jerarquía de directorios, o una mezcla de ambas. La sintaxis del comando funciona así:

tar modo[opciones] ruta...

donde modo es uno de los siguientes modos de operación (sólo se muestra una lista parcial; mira la man page de tar para ver la lista completa):

Modos de tar

c Crea un paquete de una lista de archivos y/o directorios.


Extrae un archivo.

Añade rutas específicas al final de un archivo.

Lista el contenido de un paquete.

tar usa una forma un poco extraña para expresar las opciones, así que necesitaremos algunos ejemplos para mostrar como funciona. Primero, recreemos nuestro patio de juegos del capítulo anterior:

 [me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
 [me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}


A continuación, creemos un paquete tar del patio de juegos completo:

 [me@linuxbox ~]$ tar cf playground.tar playground

Este comando crea un paquete tar llamado playground.tar que contiene la jerarquía completa del directorio playground. Podemos ver que el modo y la opción f, que hemos usado para especificar el nombre del paquete tar, pueden ir juntas, y no requieren un guión delante. Fíjate, sin embargo, que el modo siempre debe ser especificado primero, antes que ninguna opción.

Para listar los contenidos del paquete, podemos hacer ésto:

 [me@linuxbox ~]$ tar tf playground.tar

Para un listado más detallado, podemos añadir la opción v (verbose):

 [me@linuxbox ~]$ tar tvf playground.tar

Ahora, extraigamos el patio de juegos en una nueva localización. Lo haremos creando un nuevo directorio llamado foo, cambiando el directorio y extrayendo el paquete tar:

 [me@linuxbox ~]$ mkdir foo
 [me@linuxbox ~]$ cd foo
 [me@linuxbox foo]$ tar xf ../playground.tar
 [me@linuxbox foo]$ ls
 playground

Si examinamos el contenido de ~/foo/playground, vemos que el paquete ha sido instalado exitosamente, creando un reproducción precisa de los archivos originales. Hay una advertencia, sin embargo: A menos que estés operando como superusuario, los archivos y los directorios extraídos de paquetes toman la propiedad del usuario que realiza la restauración, en lugar del propietario original.

Otro comportamiento interesante de tar es la forma en que maneja las rutas en los archivos. Por defecto son relativas, en lugar de absolutas. tar hace ésto simplemente eliminando cualquier barra al principio de las rutas cuando creamos el archivo. Para demostralo, recrearemos nuestro paquete, esta vez especificando una ruta absoluta:

 [me@linuxbox foo]$ cd
 [me@linuxbox ~]$ tar cf playground2.tar ~/playground

Recuerda, ~/playground se expandirá en /home/me/playground cuando pulsemos la tecla intro, así tendremos una ruta absoluta para nuestra demostración. A continuación, extraeremos el paquete como antes y veremos que ocurre:

 [me@linuxbox ~]$ cd foo
 [me@linuxbox foo]$ tar xf ../playground2.tar
 [me@linuxbox foo]$ ls
 home   playground
 [me@linuxbox foo]$ ls home
 me
 [me@linuxbox foo]$ ls home/me
 playground

Aquí podemos ver que cuando extrajimos nuestro segundo paquete, volvió a crear el directorio home/me/playground relativo a nuestro directorio de trabajo actual, ~/foo, no relativo al directorio root, como habría sido con rutas absolutas. Ésto podría parecer una forma extraña de trabajar, pero es en realidad más útil de esta manera, ya que nos permite extraer paquetes en cualquier sitio en lugar de ser forzados a extraerlos en sus localizaciones originales. Repitiendo el ejercicio con la inclusión de la opción verbose (v) nos dará una imagen más clara de lo que está pasando.

Consideremos un ejemplo hipotético, aunque práctico, de tar en acción. Imagina que queremos copiar el directorio home y su contenido de un sistema a otro y tenemos un gran disco duro USB que usamos para la transferencia. En nuestro sistema Linux moderno, la unidad se monta "automáticamente" en el directorio /media. Imaginemos también que el disco tiene nombre de volumen BigDisk cuando lo conectamos. Para crear el paquete tar, podemos hacer lo siguiente:

 [me@linuxbox ~]$ sudo tar cf /media/BigDisk/home.tar /home

Después de que se escriba el paquete tar, desmontamos el disco y lo conectamos al segundo ordenador. De nuevo, se monta en /media/BigDisk. Para extraer el paquete, hacemos lo siguiente:

 [me@linuxbox2 ~]$ cd /
 [me@linuxbox2 /]$ sudo tar xf /media/BigDisk/home.tar

Lo que es importante ver aquí es que tenemos que cambiar primero el directorio a /, para que la extracción sea relativa al directorio root, ya todas las rutas dentro del paquete son relativas.

Cuando extraemos un paquete, es posible limitar que se extrae de él. Por ejemplo, si queremos extraer un archivo individual de un paquete, podría hacerse así:

 tar xf paquete.tar ruta

Añadiendo la ruta al final del comando, tar sólo restaurará el archivo especificado. Pueden especificarse múltiples rutas. Fíjate que la ruta deber ser tal y como está almacenada en el paquete. Cuando especificamos rutas, los comodines no están soportados normalmente; sin embargo, la versión GNU de tar (que es la versión que encontramos más a menudo en las distribuciones Linux) los soporta con la opción --wilcards. Aquí tenemos un ejemplo usando nuestro paquete playground.taranterior:

 [me@linuxbox ~]$ cd foo
 [me@linuxbox foo]$ tar xf ../playground2.tar  --wildcards 'home/me/playground/dir-*/file-A'

Este comando extraerá sólo los archivos marcados con la ruta especificada incluyendo el comodín dir-*.

tar se usa a menudo en conjunción con find para producir paquetes. En este ejemplo, usaremos find para producir una serie de ficheros e incluirlos en un paquete:

 [me@linuxbox ~]$ find playground -name 'file-A' -exec tar rf
 playground.tar '{}' '+'

Aquí usamos find para buscar todos los archivos de playground llamados file-Ay luego, usando la acción -exec, invocamos a tar en el modo inclusión (r) para añadir los archivos buscados al paquete playground.tar.

Usar tar con find es una buena forma de crear copias incrementales de un árbol de directorios o de un sistema completo. Usando find para buscar archivos más nuevos que un archivo con una marca de tiempo, podríamos crear una paquete que sólo contenga archivos más nuevos que el último archivo, asumiendo que el archivo con la marca de tiempo se ha actualizado justo antes de que se cree cada paquete.

tar puede también usar tanto entrada estándar como salida estándard. Aquí hay un ejemplo comprensible:

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name 'file-A' | tar cf - --filesfrom=- | gzip > playground.tgz

En este ejemplo, usamos el programa find para producir una lista de ficheros coincidentes y los entubamos en tar. Si el nombre de fichero "-" es especificado, toma el significado de entrada o salida estándar, según sea necesario (Por cierto, este acuerdo de usar "-" para representar entrada/salida estándar se usa en muchos otros programas también). La opción --files-from (que también puede especificarse como -T) hace que tar lea su lista de rutas de un archivo en lugar de de la línea de comandos. Finalmente, el paquete producido por tar se entuba en gzip para crear el paquete comprimido playground.tgz. La extensión .tgz es la extensión convencional dada a los paquetes tar comprimidos con gzip. La extensión .tar.gz también se usa a veces.

Aunque hemos usado el programa gzip externamente para producir nuestro paquete comprimido, las versiones modernas de tar GNU soportan tanto compresión gzip como bzip2 directamente, con el uso de las opciones z y j, respectivamente. Usando nuestros ejemplos previos como base, podemos simplificarlo de esta forma:

 [me@linuxbox ~]$ find playground -name 'file-A' | tar czf
 playground.tgz -T -

Si hubiéramos querido crear un paquete bzip comprimido, podríamos haber hecho ésto:

[me@linuxbox ~]$ find playground -name 'file-A' | tar cjf playground.tbz -T -

Simplemente cambiando la opción de compresión de z a j (y cambiando la extensión del archivo de salida a .tbz para indicar que es un archivo comprimido con bzip2) activamos la compresión bzip2.

Otro uso interesante de la entrada y salida estándar con el comando tar implica transferir archivos entre sistemas a través de una red. Imagina que tenemos dos máquinas ejecutando un sistema como-Unix equipadas con tar y ssh. En tal escenario, podríamos transferir un directorio de un sistema remoto (llamado remote-sys para este ejemplo) a nuestro sistema local:

[me@linuxbox ~]$ mkdir remote-stuff
[me@linuxbox ~]$ cd remote-stuff
[me@linuxbox remote-stuff]$ ssh remote-sys 'tar cf - Documents' | tar xf -
me@remote-sys’s password:
[me@linuxbox remote-stuff]$ ls
Documents

Así podríamos copiar un documento llamado Documents de un sistema remoto remote-sys a un directorio incluido en el directorio llamado remote-stuff en el sistema local. ¿Cómo hacemos ésto? Primero, arrancamos el programa tar en el sistema remoto usando ssh. Notarás que ssh nos permite ejecutar un programa remotamente en un ordenador conectado a una red y "ver" el resultado en el sistema local - la salida estándar producida en el sistema el sistema remota se envía al sistema local para visualizarla. Podemos sacar ventaja de ésto haciendo a tar crear un paquete (el modo c) y enviarlo a la salida estándar, en lugar de un archivo (la opción f con el guión como argumento), de esta forma transportamos el archivo a través de un túnel encriptado proporcionado por ssh en el sistema local. En el sistema local, ejecutamos tar y lo hacemos expandir un paquete (el modo x) suministrado desde la entrada estándar (de nuevo con la opción f con el guión como argumento).

zip

El programa zip es tanto una herramienta de compresión como de empaquetado. El formato de archivo usado por el programa es familiar para los usuarios de Windows, ya que lee y escribe archivos .zip. En Linux, sin embargo, gzip es el programa de compresión predominante con bzip2 muy cerca en segundo lugar.

En su uso más básico, zip se invoca así:

zip opciones archivozip archivo...

Por ejemplo, para hacer un archivo zip de nuestro patio de juegos, haríamos ésto:

 [me@linuxbox ~]$ zip -r playground.zip playground

A menos que incluyamos la opción -r para recursividad, sólo el directorio playground (pero no su contenido) se almacenará. Aunque la extensión .zip se añade automáticamente, la indicaremos por claridad.

Durante la creación del archivo zip, zip normalmente mostrará una serie de mensajes como éstos:

 adding: playground/dir-020/file-Z (stored 0%)
 adding: playground/dir-020/file-Y (stored 0%)
 adding: playground/dir-020/file-X (stored 0%)
 adding: playground/dir-087/ (stored 0%)
 adding: playground/dir-087/file-S (stored 0%)

Estos mensajes muestran el estado de cada archivo añadido al paquete. zip añadirá archivo al paquete usando uno de estos dos métodos de almacenamiento: O "almacenará" un archivo sin compresión, como hemos visto aquí, o "reducirá" el archivo realizando compresión. El valor numérico mostrado tras el método de almacenamiento indica la cantidad de compresión realizada. Como nuestro patio de juegos sólo contiene archivos vacíos, no se realizará ninguna compresión de su contenido.

Extraer el contenido de un zip es sencillo cuando usamos el programa unzip:

 [me@linuxbox ~]$ cd foo
 [me@linuxbox foo]$ unzip ../playground.zip

Una cosa a tener en cuenta sobre zip (al contrario que en tar) es que si se especifica un archivo existente, se actualiza en vez de reemplazarse. Ésto significa que el archivo existente se conserva, pero los archivos nuevos se añaden y los coincidentes se reemplazan.

Los archivos pueden listarse y extraerse selectivamente de un archivo zip especificándolo a unzip:

[me@linuxbox ~]$ unzip -l playground.zip playground/dir-087/file-Z
Archive:  ../playground.zip
Length     Date   Time  Name
--------   ----   ----  ----
       0 10-05-08 09:25 playground/dir-087/file-Z
-------- -------
       0                1 file
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ../playground.zip playground/dir-087/file-Z
Archive: ../playground.zip
replace playground/dir-087/file-Z? [y]es, [n]o, [A]ll, [N]one,
[r]ename: y
extracting: playground/dir-087/file-Z

Usar la opción -l hace que unzip sólo liste el contenido de un paquete sin extraer nada. Si no se especifican archivos, unzip listará todos los archivos del paquete. La opción -v puede añadirse para aumentar la información del listado. Fijate que cuando la extracción del paquete entra en conflicto con una archivo existente, el ususario es preguntado antes de que el archivo sea reemplazado.

Como tar, zip puede hacer uso de la entrada y la salida estándar, aunque su implementación no es tan útil. Es posible entubar una lista de nombres de archivo a zipcon la opción -@:

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name "file-A" | zip -@ file-A.zip


Aquí usamos find para generar una lista de archivos coincidentes con el test -name "file-A", y luego entubar la lista en zip, lo que crea el paquete file-A.zipconteniendo los archivos seleccionados.

zip también soporta escribir su salida a la salida estándar, pero su uso es limitado porque muy pocos programas pueden hacer uso de la salida. Desafortunadamente, el programa unzip no acepta entrada estándar. Ésto impide que zip y unzip se usen juntos para realizar copiado de archivos en red como tar.

zip puede, sin embargo, aceptar entrada estándar, así que puede usarse para comprimir la salida de otros programas:

 [me@linuxbox ~]$ ls -l /etc/ | zip ls-etc.zip -
  adding: - (deflated 80%)

En este ejemplo entubamos la salida de ls en zip. Como tar, zip interpreta el guión final como "usa la entrada estándar para el archivo de entrada."

El programa unzip permite que su salida se envíe a la salida estándar cuando se especifica la opción -p (para entubar):

 [me@linuxbox ~]$ unzip -p ls-etc.zip | less

Hemos visto algunas de las cosas básicas que puede hacer zip/unzip. Ambos tienen un montón de opciones que añadir a su flexibilidad, aunque algunas son específicas para plataformas de otros sistemas. Las man pages de zip y unzip son muy buenas y contienen ejemplos útiles. Sin embargo el uso principal de estos programas es el intercambio de archivos con sistemas Windows, en lugar de comprimir y empaquetar en Linux, donde tar y gzip son claramente preferidos.


Sincronizando archivos y directorios

Una estrategia común para mantener una copia de seguridad de un sistema implica mantener uno o más directorios sincronizados con otro directorio (o directorios) localizados en el sistema local (normalmente un dispositivo de almacenamiento removible de algún tipo) o en un sistema remoto. Podríamos, por ejemplo, tener una copia local de un sitio web en desarrollo y sincronizarlo de vez en cuando con la copia "live" en un servidor web remoto.

En el mundo como-Unix, la herramienta preferida para esta tarea es rsync. Este programa puede sincronizar tanto directorios locales como remotos usando el protocolo rsync remote-update, que permite que rsync detecte rápidamente las diferencias entre los dos directorios y realizar una cantidad mínima de copiado para sincronizarlos. Ésto hace a rsync muy rápido y económico de usar, comparado con otros tipos de programas de copia.

rsync se invoca así:

rsync opciones origen destino

donde origen y destino son uno de los siguientes:

  • Un archivo o directorio local
  • Un archivo o directorio remoto en la forma [usuario@]host:ruta
  • Un servidor rsync remoto especificado con una URI dersync://[usuario@]host[:puerto]/ruta

Fíjate que o el origen o el destino deben ser un archivo local. La copia remoto-a-remoto no está soportada.

Probemos rsync en archivos locales. Primero, limpiemos nuestro directorio foo:

 [me@linuxbox ~]$ rm -rf foo/*

A continuación, sincronizaremos el directorio playground con su copia correspondiente en foo:

 [me@linuxbox ~]$ rsync -av playground foo

Hemos incluido tanto la opción -a (para archivar - que produce recursividad y conservación de los atributos de los archivos) y la opción -v (salida verbose) para hacer un espejo del directorio playground dentro de foo. Mientras el comando se ejecuta, veremos una lista de los archivos y directorios que se están copiando. Al final, veremos un mensaje de sumario como este:

sent 135759 bytes received 57870 bytes 387258.00 bytes/sec
total size is 3230 speedup is 0.02

indicando la cantidad de copia realizada. Si ejecutamos el comando de nuevo, veremos un resultado diferente:

 [me@linuxbox ~]$ rsync -av playgound foo
 building file list ... done
 sent 22635 bytes received 20 bytes 45310.00 bytes/sec
 total size is 3230 speedup is 0.14

Fíjate que no había listado de archivos. Ésto es porque rsync detectó que no había diferencias entre ~/playground y ~/foo/playground, y por tanto no necesitaba copiar nada. Si modificamos un archivo en playground y ejecutamos rsync de nuevo:

 [me@linuxbox ~]$ touch playground/dir-099/file-Z
 [me@linuxbox ~]$ rsync -av playground foo
 building file list ... done
 playground/dir-099/file-Z
 sent 22685 bytes received 42 bytes 45454.00 bytes/sec
 total size is 3230 speedup is 0.14

vemos que rsync detectó el cambio y copió sólo el archivo actualizado.

Como ejemplo práctico, consideremos el disco duro externo imaginario que usamos anteriormente con tar. Si conectamos el disco a nuestro sistema y, de nuevo, se monta en /media/BigDisk, podemos realizar una útil copia de seguridad del sistema creando primero un directorio llamado /backup en el disco externo, y luego usando rsync para copiar lo más importante de nuestro sistema en el disco externo:

[me@linuxbox ~]$ mkdir /media/BigDisk/backup
[me@linuxbox ~]$ sudo rsync -av --delete /etc /home /usr/local/media/BigDisk/backup

En este ejemplo, hemos copiado los directorios /etc, /home, y /usr/local de nuestro sistema a nuestro dispositivo de almacenamiento imaginario. Hemos incluido la opción --delete para eliminar archivos que existieran en el dispositivo de copia y que ya no existieran en el dispositivo original (ésto es irrelevante la primera vez que hacemos una copia de seguridad, pero será útil en sucesivas copias). Repitiendo el procedimiento de conectar el disco externo y ejecutar este comando rsync sería una forma útil (aunque no ideal) de mantener un pequeño sistema respaldado. De acuerdo, un alias sería muy útil aquí, también: Podríamos crear un alias y añadirlo a nuestro archivo .bashrc para tener la utilidad:

alias backup='sudo rsync -av --delete /etc /home /usr/local/media/BigDisk/backup'

Ahora, todo lo que tenemos que hacer es conectar nuestro disco externo y ejecutar el comando backup para realizar el trabajo.

Usando rsync a través de una red

Uno de los verdaderos encantos de rsync es que puede usarse para copiar archivos a través de una red. Después de todo, la "r" de rsync significa "remoto". La copia remota puede hacerse de dos formas. La primera es con otro sistema que tenga rsyncinstalado, a través de un programa shell remoto como ssh. Digamos que tenemos otro sistema en nuestra red local con mucho espacio disponible en el disco duro y queremos realizar una operación de copia de seguridad usando el sistema remoto en lugar de un disco externo. Asumiendo que ya hay un directorio llamado /backup donde podríamos depositar nuestros archivos, podríamos hacer ésto:

[me@linuxbox ~]$ sudo rsync -av --delete --rsh=ssh /etc /home/usr/local remote-sys:/backup

Hemos hecho dos cambios en nuestro comando para facilitar el copiado a través de la red. Primero, hemos añadido la opción --rsh=ssh, que le dice a rsync que use el programa ssh como su shell remoto. De esta forma, podemos usar un tunel ssh encriptado para transferir datos con seguridad desde el sistema local hasta el host remoto. Segundo, hemos especificado el host remoto añadiendo su nombre (en este caso el host remoto se llama remote-sys) como prefijo de la ruta de destino.

La segundo forma en que podemos usar rsync para sincronizar archivos a través de una red es usando un servidor rsync. rsync pude configurarse para funcionar como un demonio y escuchar solicitudes remotas de sincronización. Ésto se hace a menudo para realizar copias espejo de un sistema remoto. Por ejemplo, Red Hat Software mantiene un gran repositorio de paquetes de software en desarrollo para su distribución Fedora. Es útil para testeadores de software replicar esta colección durante la fase de testeo del ciclo de liberación de la distribución. Como los archivos en el repositorio cambian con frecuencia (a menudo más de una vez al día), es recomendable mantener una copia espejo local con sincronización periódica, en lugar de copiar todo el repositorio. Uno de esos repositorios está alojado en Georgia Tech; podríamos clonarlo usando nuestra copia local de rsync y su servidor rsync así:

[me@linuxbox ~]$ mkdir fedora-devel
[me@linuxbox ~]$ rsync -av -delete rsync://rsync.gtlib.gatech.edu/fed
ora-linux-core/development/i386/os fedora-devel


En este ejemplo, hemos usado la URI del servidor rsync remoto, que consiste en un protocolo (rsync://), seguido del nombre de host remoto (rsync.gtlib.gatech.edu), seguido de la ruta del repositorio.


Resumiendo

Hemos viso los programas más comunes de compresión y empaquetado en Linux y otros sistemas operativos como-Unix. Para empaquetar archivos, la combinación tar/gzipes el método preferido en sistemas como-Unix mientras que zip/unzip se usa para interoperar con sistemas Windows. Finalmente, hemos visto el programa rsync (mi favorito personal) que es muy útil para sincronizar eficientemente archivos y directorios entres sistemas.

Para saber más

  • Las man pages de todos los comandos vistos aquí son muy claras y contienen ejemplos útiles. Además, el proyecto GNU tiene un buen manual online para su versión de tar. Puede encontrarse aquí:
    http://www.gnu.org/software/tar/manual/index.html

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.