Backup automático de dispositivos externos

cómo proteger nuestro pendrive ante pérdida de datosImagina por un momento que se te estropea la memoria del móvil o pierdes el pendrive que, como buen informático que eres, llevas siempre encima “por lo que pueda pasar” ;)

  • ¿tienes copia de seguridad de alguno de ellos?
  • ¿cuándo fue la última vez que te acordaste de hacer una copia de respaldo por lo que pudiese ocurrir?

Mira que a los informáticos nos gusta hacer la famosa pregunta “¿tienes copia de seguridad?” cada vez que alguien viene a nosotros porque se le ha estropeado el ordenador o le ha dejado de funcionar su memoria externa pero… ¿las hacemos nosotros?

La experiencia me dice que en casa de herrero… cuchara de palo y es que tengo muy claro que

  • por muchas herramientas que existan para facilitar la creación de copias de seguridad y
  • por muy sencillas que sean (aunque sólo sea pulsar un botón)

si tenemos que acordarnos de hacerlo pueden pasar eones entre un backup y otro ;)

¿Qué te parecería automatizar las copias de seguridad de nuestros dispositivos de almacenamiento? Pues éso es lo que vengo a ofreceros: una forma de olvidarnos de hacerlo manualmente en la que, cada vez que pinchemos nuestro dispositivo al ordenador, el equipo se encargará de guardar en disco una copia de aquellos directorios que le indiquemos por lo que pueda pasar.

Idea a desarrollar

Sencilla (menos es más)

  1. crear una regla que detecte nuestros dispositivos (udev)
  2. un script que realice la copia si el dispositivo está entre los que nos interesan

El script

  1. utilizará rsync para copiar sólo los cambios que se hayan producido desde el último backup
  2. incluirá una lista con los identificadores de los dispositivos que nos interesan
  3. para cada dispositivo externo indicaremos los directorios que deseamos proteger (puede que del móvil sólo nos interese el directorio de las fotos/vídeos y algún que otro directorio más pero puede que el de la música sea prescindible por tenerlo en el ordenador descargado)

Implementación

Regla udev

Crearemos el fichero /etc/udev/rules.d/96-backupPendrives.rules con el siguiente contenido

SUBSYSTEMS=="usb", DRIVERS=="usb", KERNEL=="sd*", ACTION=="add", RUN+="/home/jasvazquez/Dropbox/apps/backup-pendrives.sh $kernel"

NOTA:cambia la ruta /home/jasvazquez/Dropbox/apps/backup-pendrives.sh para que apunte al script que veremos en el siguiente apartado.

Para que la regla comience a funcionar sin tener que reiniciar el equipo deberás lanzar

 sudo udevadm control --reload-rules

NOTA: ten en cuenta que estoy utilizando Archlinux, en tu distribución puede que varíe levemente el modo de reiniciar udev.

Con la regla recién cargada conseguiremos que se lance el script backup-pendrives.sh cada vez que se monte un dispositivo externo en nuestro equipo.

Script a ejecutar

El contenido del script puedes obtenerlo de la siguiente dirección [Descargar script backup].

En principio no voy a cansaros con los detalles de implementación del script, para aquellos que, como a mi, os gusta bichear el código de otros como medio de aprendizaje, os invito a hacer las preguntas que consideréis oportunas en los comentarios de esta entrada.

Según donde descargues el script recuerda modificar convenientemente la ruta en la regla udev (y recargarla si cambias algo).

Configuración

Debes personalizar el código del script para que se adapte a tus necesidades particulares; en concreto:

Directorio backup

Debemos indicar la ubicación donde queremos que el script copie los cambios que se vayan produciendo en cualquier fichero de nuestros dispositivos externos

crear copias de seguridad automáticas memory stick

Dispositivos a respaldar

Para cada dispositivo (p.e. 33E5-E730) indicaremos (separando con ; cada uno de ellos) los directorios que nos interesa proteger (p.e. /logos;/logos2/kk si queremos proteger /logos y el directorio /logos2/kk)

configurar la automatización de los backups en linux

La forma más sencilla de conocer el identificador de cada dispositivo es la de conectarlos y observar el punto de montaje en el directorio /media (que suele ser el que utilizan muchas distribuciones).

En la siguiente captura se observan los identificadores de mi HTC Magic (61F2-1AFF) y un pendrive (33E5-E730) cualquiera

simplificar copias de respaldo automáticas

Conclusión

Solución que llevaba mucho tiempo queriendo implementar y que considero que por su simplicidad y eficiencia nos ayuda a resolver un problema que nos podría dar más de un dolor de cabeza.

Sin ir más lejos, que mi mujer creyese haber perdido el pendrive del instituto, en el que guardaba la documentación con la que trabajaba en plenas evaluaciones finales, fue el detonante que me animó a mejorar el posicionamiento de esta “tarea de baja prioridad” que tenía en background dese hace ya casi dos años (demasiados proyectos e ideas para tan poco tiempo… sorry).

A partir de ahora, cada vez que pinche su pendrive en el equipo del despacho, sin ella saberlo, tendrá una copia de seguridad de todo su contenido; no tiene precio, ¿no os parece? ;) (I love Linux!)

31 comentarios en “Backup automático de dispositivos externos

  1. Manuel Pérez dijo:

    Hola, lo prometido es deuda así que he probado tu script y funciona de maravilla en Ubuntu. Ahora mismo está haciendo copia de seguridad de mi teléfono y un usb que uso para pasar información importante del trabajo.

    He seguido todos los pasos que has descrito, cambiando sólo la ruta dónde se copian los backups y la localización del script.

    Un saludo y gracias por este aporte tan útil.

  2. Julio dijo:

    Muy bueno el script, para un profesor puede ser la forma de almacenar los trabajos de los chicos de manera transparente, claro que también se llevaría cualquier otro contenido que hubiera en el lápiz.

    También se me ocurre que sería bueno hacerlo a la inversa, cuando meta el lapíz A se he hace el backup de la ruta 1 al lápiz A.

    Dicho esto para evitar susceptibilidades de terceros , le pondría mensajes en la pantalla de lo que ha hecho automáticamente el sistema para tranquilidad de todas las partes.

    • No se llevaría cualquier contenido puesto que para eso se definen, por cada dispositivo y separados por “;”, los directorios que te interesa copiar.

      La opción “inversa” que indicas ha sido analizada (que no implementada) para copiar a un hd externo usb que tengo una copia de todos los backups que haya en el equipo. En teoría (falta probarlo) sería tan sencillo como meter un nuevo ID de dispositivo (el del hd externo) e indicar para él la ruta que quiero del ordenador.

      Los mensajes son un deseable para informar al usuario tanto para tranquilizar al usuario como para que no quite el pendrive antes de tiempo y se fastidie algo (notify-osd haría milagros en esta faceta).

      De momento me conformo con la versión peta-beta inicial (cumple objetivos mínimos). Si alguien mejora el script agradeceré que avise para que todos nos beneficiemos de las mejoras; por mi parte, ya sabéis que si cambio algo os lo haré saber ;)

  3. Interesante. Aunque para los Backups, prefiero hacerlo a mano. Uso habitualmente Grsync, y con el hago copias, sobretodo, de carpetas del sistema al HD externo, para tener las cosas importantes por duplicado.

    No se, me gusta tener el control de lo que estoy haciendo :).

    Por otro lado, siempre llevo un pendrive a clase, pero ahora mismo casi no lo uso, Dropbox se encarga de la mayor parte del trabajo que hacía la memoria USB. Muy recomendable este servicio.

    Saludos!!

  4. Segurata dijo:

    Muy buena entrada informático de guardia! Me he decidido a escribir un comentario (a parte de para felicitarte por el aporte) para pedirte/preguntarte/sugerirte cómo darle una vuelta de tuerca más a esta buena técnica. La idea es que estos dispositivos externos plantean problemas de seguridad en caso de extravío/pérdida/robo, por tanto, lo ideal es que vayan al menos en una parte cifrados, teniendo una partición libre y otra cifrada para paliar este problema de seguridad.

    Mi sugerencia es que ya que has hecho una entrada para hacer particiones en un pendrive (https://andalinux.wordpress.com/2008/10/03/crear-particiones-graficamente-en-un-pendrive-con-gparted/), otra para hacer copias automáticas, te falta una para cifrado e integrarlo todo en la copia automática (para que cuando te pida la clave de descifrado haga el respaldo).

    • No es mala sugerencia y, como bien indicas, sería el complemento ideal.
      El tratar las particiones cifradas lo tengo como tema pendiente desde hace tiempo pero nunca me animo a publicar sobre ello al requerirme invertir algo de tiempo el tener que probar alguna de las soluciones que más me llaman la atención (por lo que siempre se queda en segundo plano :()
      Con un poco de suerte, el veranito me permite sacar algo de tiempo para investigar, prometo compartir las conclusiones ;)
      Gracias por comentar @Segurata pero la próxima vez deja un correo electrónico válido por si quiero “contarte algo” (descuida que no me dedico a la venta de emails jejeje)

      • Segurata dijo:

        Jeje, esperaré tu entrada sobre el tema que seguro que está genial ;).

        Realmente aunque no te puse mi dirección la conoces por ser ya “viejo” lector de tu blog y que además una vez usé tu soporte técnico jeje. No temo que comercies con mi dirección web, pero las costumbres, manías o inercia a la hora de no poner mi mail es complicado de cambiar (ahora te la he puesto correctamente).

        Un saludo y hasta ahora.

  5. Te agradezco que escribas el correo electrónico (recibo bastantes comentarios y solicitudes de ayuda como para encontrar los correos fácilmente ;))

    Procuraré aumentar la prioridad al artículo sobre encriptación pero no prometo nada que no sé cómo se va a presentar de movido el veranito ;)

  6. rifle69 dijo:

    Buenas, magnifico post, yo había tenido una idea igual, pero no lo sabia llevar acabo.

    Tengo un par de dudas, espero que no sea una molestia preguntarlas por aqui:

    pendrives["HD_BACKUP"]

    En la anterior linea, lo que va entre comillas, es decir, HD_BACKUP, es el id que el sistema asigna al usb no?

    ¿Hay que modificar algo mas? Aparte claro esta de la dirección a la que quiero hacer la copia de seguridad.

    En la LIST_BAK_DIRS hay que escribir las carpetas del usb que queremos guardar no?

    Yo voy a añadir un cuadro de texto cuando compruebas si el dispositivo esta en la lista, que nos informe de que no esta. Y si puedo y se, (no tengo mucha experiencia en estas cosas) intentare poderlo añadir desde otra ventana, pero eso es un sueño por ahora.

    Lo que si voy a añadir es que comprima en algún formato (.tar, .tar.gz, .rar) dicha copia. Para sobre todo ahorrar espacio.

    Si quieres cuando lo tenga lo pongo en un comentario o lo que quieras.

    Un saludo y muchas gracias por el post porque es muy util la verdad.

    Perdón por las faltas de ortografía, ando con bastante prisa, jajaja.

    Un saludo

  7. Yo no me molesto en comprimir porque voy pensando en fotos y vídeos y en ellos poco voy a ganar amén de no poder aprovechar la gracia de rsync que es reducir el coste de hacer la copia a sólo los cambios (comprimir tendrás que comprimir todo)

    Mostrar un mensaje cuando el dispositivo no le veo la utilidad (explícame la finalidad si no es molestia) puesto que si no lo tengo definido para qué quiero ver mensajes cada vez que pincho algo al ordenador (otra cosa sería meter la posibilidad de añadir “automágicamente” el dispositivo a la lista si no está ;))

    Mantenemos el contacto y nos retroalimentamos… cualquier ayuda, mejora y/o sugerencia es bien recibida

  8. rifle69 dijo:

    Eso la verdad esta bien pensado, pero una vez el archivo comprimido se pueden añadir solo los cambios que nos sincronice el rsync pero esta bien pensado.

    El cuadro de información es para tener la posibilidad de sino esta en la lista poderlo añadir.

    El mensaje sería el mismo que usted ha puesto y un ¿Quiere añadir dicho usb a la lista? o algo así.

    Si pulsa que si, o añadir, pues que se añada, si no, pues no, esa es la finalidad del cuadro de texto.

    Sino añado esa posibilidad no lo pondría ya que sería un poco molesto el cuadro de texto cada vez que lo conecte.

    Veo complicado que lo pueda hacer, de todas maneras, dentro de nada tendré tiempo y lo investigaré.

    Un saludo

  9. Julio dijo:

    Hola de nuevo, tengo una duda.

    Generalmente el lápiz tiene una sola partición, pero es posible encontrarnos con dispositivos usb con más de una partición. De hecho yo los uso por la limitación del fat32 y los 4 GB por fichero.

    Mi pregunta es cuando el sistema detecta un USB con más particiones, ¿el sistema GNU/Linux se ejecutará tu archivo de script una vez por partición?

    Otra cosa, sigo dándoles vueltas al script y estaba pensando en independizar los datos de los backups del script mismo.

    Básicamente necesito una base de datos donde guardar al menos los datos que necesito para enviarle a rsync.

    Estaba barajando dos opciones:
    1.- Fichero csv
    2.- Base de datos SQLite

    Ambas opciones tienen sus ventajas e inconvenientes. Además si quieres ser un poco paranoico puedes llevar la contabilidad de todos los dispositivos que conectes al sistema, pero esto es otro tema

    Por ejemplo con un fichero csv un posible código sería:

    #!/bin/bash

    # Objetivo del programa: Hacer que tú sistema nada más introducir un USB en el mismo haga lo siguiente:
    # Lo de de alta en un fichero csv para que puedas programas lo que quieras sincronizar en el
    # Sincronizar en el usb o los datos contenidos en una carpeta del mismo o los datos que queramos de una carpeta de nuestro equipo
    # Este script deberá en todo momento avisar de lo que está haciendo visualmente al usuario
    # La idea en que se basa este programa se puede ver en este enlace https://andalinux.wordpress.com/2011/07/04/backup-automatico-de-dispositivos-externos/

    # Se necesita algunos programas externos, que son:
    # el paquete notify-send para hacer visible los mensajes de las acciones que va haciendo el programa.
    # Ver estos enlaces para documentación http://www.userlinux.net/1393_notify_send.html http://www.linuxjournal.com/content/tech-tip-get-notifications-your-scripts-notify-send

    # Se necesita un fichero de texto en formato csv para indicar las acciones que luego ejecutará el programa
    # El formato del fichero será almenos esto
    # IDUSB;Accion_a_realizar[1|0];Ruta_origen;EsUSBlarutaOrigen[0|1];Ruta_destino;EsUSBlarutaDestino[0|1];Desmontar_al_acabar[1|0]
    # 1 significa que Sí se hace la acción a realizar y 0 siginifica que no se hace
    # Todas las rutas son relativas, USB->Disk
    # La idea es tener una línea por acción

    IconoOK=”/usr/share/icons/Nuvola/scalable/actions/dialog-ok.svg”
    IconoDisco=”/usr/share/icons/Nuvola/scalable/devices/drive-harddisk.svg”
    IconoAyuda=”/usr/share/icons/Nuvola/scalable/actions/help-about.svg”
    BasedeDatos=”/home/jra/basededatosdeusb.csv”

    if [ -e $BasedeDatos ]
    then
    # la base de datos existe
    echo “La base de datos $BasedeDatos ya existe. No la volvemos a crear”
    else
    # Creamos el fichero $BasedeDatos
    touch $BasedeDatos
    # Creamos la línea IDUSB;Accion_a_realizar[1|0];Ruta_origen;Ruta_destino;Desmontar_al_acabar[1|0]
    echo “IDUSB;Accion_a_realizar[1|0];Ruta_origen;EsUSBlarutaOrigen[0|1];Ruta_destino;EsUSBlarutaDestino[0|1];Desmontar_al_acabar[1|0]” >> $BasedeDatos
    # Avisamos al usuario
    notify-send -i $IconoOK “Hemos creado $BasedeDatos”
    fi
    # nos hemos asegurados que el fichero de base de datos existe

    # Obtenemos el ID del USB
    # añadir el codigo de andalinux
    IDUSB=”2F18-7F61″

    # Comprobamos que el usb esté definido en nuestra base de datos
    Aux=`grep $IDUSB $BasedeDatos`
    Equivalencia=${#Aux}
    if [ $Equivalencia = "0" ]
    then
    # No está el usb, lo añadimos a la base de datos
    echo “$IDUSB;0;;0;;0;0″ >> $BasedeDatos
    notify-send -i $IconoDisco “Edíte $BasedeDatos. si quiere programar un backup.”
    else
    echo “El USB $IDUSB está en la base de datos. No hacemos nada”
    fi

    # La base de datos ha podido cambiar así que recalculamos de nuevo, aunque no para hacer nada
    #miramos de nuevo en el fichero de base de datos para realizar las operaciones descritas en el mismo
    Aux=`grep $IDUSB $BasedeDatos`
    echo $Aux
    if [ $Equivalencia = "0" ]
    then
    # No hay nada que hacer en la base de datos
    echo “No se debería pasar por aquí, excepto la primera vez”
    else
    echo “Empezamos a procesar el $IDUSB en nuestra base de datos”
    # Completar el codigo ….
    fi

    ¿Qué opináis de independizar el dato del script?
    ¿Cuál consideras que es mejor opción csv o SQLite?

    Gracias, Julio.

  10. En un principio me planteé la necesidad de separar los datos como indicas pero opté por hacerlo utilizando arrays ya que el volumen de dispositivos a gestionar es pequeño y no quería que el script dependiese de librerías o programas que no suelen estar instalados en cualquier equipo.

    Objetivo: simplicidad (acceder a un array es trivial) y compatibilidad.

    Evidentemente si necesitas poder definir nuevos dispositivos “en caliente” habría que buscar un mecanismo de persistencia.

    Buscando evitar dependencias con programas descartaría sqlite (aunque a todas luces es la forma más cómoda y potente de trabajar con la información al no tener que parsear los datos)

    Yo tiraría por ficheros para serializar y deserializar el array de modo que pueda descargarlo/cargarlo y seguir utilizando arrays tal y como está ahora (tener que parsear un fichero csv desde bash, aunque no es complicado guarrearía demasiado el script que tenemos)

    Respecto a la identificación de las particiones no me preocuparía ya que la regla udev escanea las distintas particiones y cada una de ellas tiene un identificador único ;)

  11. Hola, muy buenas! Enhorabuena por tu post. Tengo un pregunta, el identificador del dispositivo que se tiene que poner es que el aparece en el comando: lsusb o el que monta en /media

    Por otro lado el script no me esta funcionando y no se por que. He intentado trazarlo y el problema es del script dado a que se esta lanzando correctamente. Mi variable de entorno $kernel no tiene valor ¿Puede ser por eso?

    Gracias!

    • Bueno, siempre es bueno encontrar (y corregir) fallos: así conseguimos que sea lo más fiable y robusto posible ;).

      Como se indica el identificador tiene que ser el que aparece en /media.

      ¿Tus dispositivos usb son identificados por el sistema como /dev/sdXXX? si no es así, la regla udev no los filtrará y por tanto no invocará el script.

      Como el problema puede ser largo de encontrar te agradecería mantener esta “conversación” a través del soporte técnico informático que ofrezco gratuitamente en el blog ;), ¿te parece?

  12. Hola, muy buenas. Te llevo siguiendo desde el anonimato durante un tiempo y la verdad es que me ha parecido una brillante idea que lleves a cabo la realización de este script. Además he aprendido mucho de él.
    Pero tengo un par de preguntas, la primera es que cual es exactamente la función del parámetro “typeset -A pendrives”.
    La segunda es en el parametro de cut. Yo lo habría hecho con sed (más que nada porque trabajo mejor con el) con esta orden ” … | sed -e s/ID_FS_LABEL=//g “. Pero tu en cambio pones ” cut -d= -f2 ” , osease no estableces ningun delimitador, y marcas el segundo campo (-f2) , pero ¿como vas a marcar el campo si no tiene ningún delimitador?
    Gracias por tu tiempo informático de guardia. Saludos.

    • Me alegra que te hayas animado a comentar (en caso contrario Bender hubiese hecho de las suyas ;))

      “typeset -A” permite definir un array “asociativo” en el que se utilizan claves no numéricas para referenciar las entradas del mismo.

      Espero que te ayude a aclarar la duda.

  13. Rectifico la última pregunta, ayer mismo me dí cuenta que el parámetro -d=, apunta al = como delimitador, cuando yo pensaba que era un igual de comparación, y que se comparaba al vacío.
    Espero tu respuesta de la primera pregunta! :)

  14. Hola, muy buenas. Me encanta tu blog, hay información muy útil!

    Estaba modificando el Script para que me mostrase notificaciones mediante notify-send cuando el dispositivo no esta en la lista y cuando se inicia y termina la copia.

    Del siguiente modo:

    # Si no existe el dispositivo, hemos terminado (nada que hacer)

    if [[ ! ${pendrives[$ID_PENDRIVE]} ]]; then

    logger “El dispositivo $ID_PENDRIVE no se encuentra en nuestra lista de pendrives a los que realizar copia de segurida”

    notify-send “Dispositivo externo” “El dispositivo $ID_PENDRIVE no se encuentra en nuestra lista de pendrives a los que realizar copia de segurida” -i notification-device-usb
    exit -1;
    fi

    Todo correcto, pero introducir un usb que no esta en la lista no aparece, a su vez si ejecuto manualmente el Script si aparecen los mensajes correspondientes. Creo que puede ser algún problema de permisos, pero le he asignado 775, 777, he intentado modificar el grupo de usuario y tampoco funciona.

    Espero tu respuesta, y si conseguimos que todo funcione, se podría implementar en el soruce original si te parece.

  15. izkalotl dijo:

    Excelente aporte amigo, funcionado al 100% en Ubuntu 10.04 seria bueno darle interfaz grafica con Zenity, no se yo nada de programación de scripts pero voy a ver que se puede hacer y te comento.

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s