Luis Angel Cofiño

Trucos Linux

Backup desatendido: mi antiguo script





Secciones

Índices

 

Mi antiguo script

Actualmente, mis script de seguridad van de otra forma, pero el método que voy a describir aquí funcionó correctamente y sin problemas durante años. Quizás a alguien le interese, aunque yo lo haya abandonado por el sistema nuevo, pero seguro que hay más de una idea aprovechable. De hecho, los scripts que uso ahora han sacado muchas ideas de aquí. ¿Empezamos?.

Vereis, pues resulta que en mi máquina tengo varias particiones. Una de ellas es /dev/hda3, una partición primaria de 5 GB que NUNCA está montada, y que solo root puede montar. Esa partición se monta como /mnt/seguridad, y es ahí donde van a parar las copias de seguridad más importantes, de forma rotatoria y según una estrategia preestablecida mediante un pequeño script.

¿Cómo funciona esto?. Pues en la partición de seguridad existen dos directorios: volcado_impar y volcado_par. El primer día se hace una copia completa de todos los ficheros importantes (solo los importantes) en volcado_impar. El segundo día se hace una copia incremental, solo de los ficheros modificados desde ayer. El tercer día otra vez. Y así sucesivamente hasta, pongamos, el día 15. Entonces el script hace "click" y cambia al directorio volcado_par, borra todo lo que haya, y hace una copia completa (no incremental) de todos los ficheros. El día 16 hace otra copia incremental, y así sucesivamente hasta el día 30, en que vuelve a cambiar a volcado_impar. ¿Correcto?.

Total, que si por cualquier motivo el ordenador se va al carajo tienes intacta toda la información con una garantía de 24 horas.Y además, grabada por etapas, de tal forma que si sabes qué día se produjo el problema, no tienes que revisar toda la copia de seguridad, solo la de ese día. Y además lo conserva todo por duplicado (la copia completa actual y la previa, por si acaso). Y ya por pedir, también se graba un log de todo lo que va ocurriendo.

Y (ahí está la gracia), el atribulado usuario no tiene que hacer NADA. El script funciona de forma completamente automática y toma todas las decisiones.

Lo pongo aquí porque este script me ha salvado el cuello en tres o cuatro ocasiones. Incluso protege contra un formateado accidental de disco duro, puesto que se trata de una partición aparte que ni siquiera está montada ni el usuario puede montar.

El punto más débil del script es que no protege contra un fallo físico del disco duro. Bien... podría decir un par de cosas sobre eso, también. Porque, de hecho, una de las veces que me salvó el cuello, el fallo había sido precisamente un fallo físico. Pero ocurrió que como la partición de seguridad no estaba montada en el momento del error, quedó intacta y pude acceder a ella (casi de milagro, con un maravilloso disco de arranque linux especialmente útil en emergencias). Así, conviene extraer la información a un medio externo, por ejemplo un CD-RW. Por eso modifiqué el script para dejar preparada una imagen ISO, lista para ser quemada en la grabadora.

Básicamente, y traducido al cristiano, lo que hará el script es lo siguiente:

  1. Se asignan todas las variables.
  2. Si hemos pedido un reset se crean todos los ficheros de registro y de log, así como todos los ficheros que actuarían como contadores. En condiciones ideales, esta opción solo haría falta ejecutarla la primera vez. En la práctica, tuve que reescribir y reiniciar el script varias veces a lo largo de su existencia. ;-)
  3. Si hemos pedido que sea completo, se modifica la variable que hace de contador para que se ponga al final de la serie, y después sigue con el script (esto hará que el script de un salto y empiece un backup completo).
  4. Cargamos qué directorios queremos salvar.
  5. Chequeamos si la partición de seguridad está montada. Si lo está "alguien" se ha despistado, porque no debería, pero no es un fallo importante, así que avisamos en el log, y seguimos. Si no está montada intentamos montarla. Si no se puede, algo va muy mal y abortamos (aviso gordo en el log). Si se monta sin problemas, seguimos adelante.
  6. Miramos el contador de "número de backups".Si ha llegado al final, cambiamos la variable que indica el directorio activo y ponemos el contador en cero.
  7. Avisamos al log de que esto va a empezar, y ponemos en el home un archivo con el listado de los paquetes de software instalados en el sistema. ;-)
  8. Empieza la fiesta. Tar hace la copia de seguridad, con los debidos avisos al log.
  9. Comprueba el tamaño de la copia de seguridad y también lo anota en el log.
  10. Elimina el archivo con el listado de paquetes (ya ha sido copiado, así que no hace falta).
  11. Si la copia fue completa entonces la parte en trozos que quepan en un CD-RW. Después coge esos trozos y los transforma en una imagen ISO, lista para ser quemada. Envía un mensaje al log, indicando que ya se pueden tostar los CDs en cuanto se quiera.
  12. Sumamos uno al contador de backups.
  13. Almacenamos el valor actual del contador, comprimimos el log para que no ocupe mucho, y desmontamos la partición de seguridad. Final.

Bueno, esto es lo que hace traducido al cristiano, pero vamos a ver el script tal y como es de verdad. Los que tengan un navegador que admita hojas de estilo, observad que he coloreado la sintaxis de forma parecida a como lo hace el editor vim (de nada, uno que es así de majo).

Y observad también que aparecen secuencias de escape en los mensajes que se redirigen al fichero log. Esto sirve para que el log aparezca coloreado cuando se consulte. ;-)

------------- comienzo del script "asegurar" / corte aquí ----------
#!/bin/sh
# Autor: Luis Angel Cofiño. Este script está diseñado para un 
# ordenador concreto. Probablemente no funcione en el suyo, 
# pero quizás quiera modificarlo para adaptarlo a sus intereses
#
# "asegurar": para operacion normal
#
# "asegurar reset": para preparar el disco (crear registros, logs...)
#                   Excepto crear la partición de seguridad, claro. 
#		    (Eso hay que hacerlo a mano, que con esas cosas 
#		    no se juega).
#
# "asegurar completo": Hace un backup total y resetea los contadores.
#
# ----------- Primero definimos directorios y variables
fecha=`date +"%Y-%m-%d"` #fecha y hora de inicio del backup
volcado_reset="15" #cada 15 dias volvemos a empezar.
volcado_dir="/var/log/volcado_duro.dir" #directorio que usamos.
directorio=`cat $volcado_dir` #Lo lee y lo carga en otra variable.
nivel=`cat /var/log/volcado_duro.nivel` #cuantas copias llevamos.
gunzip /var/log/asegurados_duro.log.gz #descomprimimos log
registros="/var/log/asegurados_duro.log" #aquí guardaremos los logs
particion="/mnt/seguridad" #esta es la partición "de guerra"
frena="nice -n 19 " #baja prioridad, que no estorbe.

normal=$'\e[0m' #definimos los colores ANSI. rojo=$'\e[1;31m' verde=$'\e[1;32m' amarillo=$'\e[1;33m' azul=$'\e[1;34m' rosa=$'\e[1;35m' cyan=$'\e[1;36m' blanco=$'\e[1;37m'
# ---- ¿Hemos pedido un reset? # Pues empezamos en directorio impar if [ "$1" = "reset" ] ; then echo "impar" > /var/log/volcado_duro.dir volcado_dir="/var/log/volcado_duro.dir" directorio=`cat $volcado_dir` nivel="$volcado_reset" #reseteamos mount $particion #montamos y creamos directorios mkdir $particion/volcado_par mkdir $particion/volcado_impar mkdir $particion/split touch $particion/.comprobacion umount $particion echo " " > /var/log/asegurados_duro.log #Creamos el log. fi # ---- Si pedimos "completo" nos ponemos en nivel 15 # con lo que la próxima vez hará copia completa if [ "$1" = "completo" ] ; then echo $volcado_reset > /var/log/volcado_duro.nivel gzip $registros exit 0 fi
# ---- Directorios a salvar aa="/home/lacofi" bb="/home/maria" cc="/home/usuarios" dd="/etc" ee="/root" ff="/opt/programas-usuario" gg="/var/lib/mysql" hh="/var/lib/dosemu"
# ---- Vamos a comprobar que la unidad se monta. # y si no es así sacamos una advertencia. if test -f $particion/.comprobacion ; then echo $rojo"--------------------------"$normal >> $registros echo $amarillo`date +"%d/%m/%Y"`$normal >> $registros echo "El disco de seguridad"$rojo" ya está montado."$normal >> $registros echo $rojo"¡Este disco solo se monta para backup!"$normal >> $registros echo "Bueno, "$amarillo"seguimos,"$normal" por esta vez." >> $registros else #...pero seguimos adelante. mount $particion status=$? #Si al montar falla, ¡abortar!. if [ "$status" -ne 0 ] ; then echo $rojo"¡ERROR al montar /dev/hda3!"$normal >> $registros echo "Asegúrate de que la unidad está bien" >> $registros echo "Fin: "$rojo"ERROR"$normal$amarillo"Uy, uy."$normal >> $registros gzip $registros exit 1 fi fi # ---- Ahora unas cuantas decisiones. # qué hacer cuando hemos llegado al reset. if [ "$volcado_reset" = "$nivel" ] ; then nivel=0 echo $rojo"--------------------------"$normal >> $registros echo $rosa"Se ha reiniciado el Backup"$normal >> $registros echo $rosa"El antiguo Backup es "$directorio$normal >> $registros if [ "$directorio" = "par" ] ; then echo "impar" > /var/log/volcado_duro.dir directorio=`cat /var/log/volcado_duro.dir` else echo "par" > /var/log/volcado_duro.dir directorio=`cat /var/log/volcado_duro.dir` fi rm $particion/volcado_$directorio/seguridad* rm /var/log/recuento_backup.log echo $rosa"El nuevo Backup es "$directorio$normal >> $registros fi
# ---- Y por fin vamos allá # Ponemos también en mi home una lista de los # paquetes que están instalados en este momento # para guardarla con el backup. echo $cian"--------------------------"$normal >> $registros grabacion=`date +"%d/%m/%Y"` echo $amarillo$grabacion$normal >> $registros echo "Nivel "$rojo$nivel$normal" en "$rojo"volcado_$directorio"$normal >> $registros apt-cache pkgnames | sort > /home/lacofi/listado_instalados.txt
$frena tar -cz \ -f $particion/volcado_$directorio/seguridad-$fecha-nivel$nivel.tar.gz \ --listed-incremental=/var/log/recuento_backup.log \ $aa $bb $cc $dd $ee $ff $gg $hh 2>> $registros echo "Creado "$verde"seguridad-$fecha-nivel$nivel.tar.gz"$normal >> $registros lectura=`ls -Fhl $particion/volcado_$directorio/seguridad-$fecha-nivel$nivel.tar.gz` echo "Tamaño: `/opt/programas-usuario/elige $lectura`" >> $registros # ---- Lo de arriba llama a un scrip externo para determinar el tamaño # del fichero de backup (lo veremos después). # ---- Lo de abajo borra la lista de paquetes (no la necesitamos más) rm /home/lacofi/listado_instalados.txt # ---- Si el backup era completo hay que borrar # el directorio split y partir el fichero en trozos if [ $nivel = 0 ]; then rm -f $particion/split/* cd /tmp mkdir partido cd partido rm -f * $frena split -b 645m \ $particion/volcado_$directorio/seguridad-$fecha-nivel$nivel.tar.gz \ seguridad-$fecha-nivel$nivel.tar.gz. for bucle_arch in `find . -print` do if [ -d "$bucle_arch" ]; then echo "¡Ups!, $bucle_arch directorios...¿?" >> $registros else $frena mkisofs -V \ "volumen_seg" -o "$particion/split/$bucle_arch.iso" \ -R $bucle_arch #Creadas imágenes ISO, fi done echo "El fichero ha sido partido en $particion/split" >> $registros echo $rojo"¡¡Es el momento de usar la grabadora!!"$normal >> $registros cd /tmp/partido/. rm -f * #Un poco de limpieza. cd .. rmdir partido cd fi nivel=`expr $nivel + 1` #Y sumamos uno al contador.
# ----------- Preparación del siguiente backup y final echo $nivel > /var/log/volcado_duro.nivel $frena gzip $registros umount $particion
-------------------- Aqui termina "asegurar" / cortar aqui -----------------

¿Lo habeis visto?. Así es como funciona. Vale, vale, no soy un genio de la programación ni lo pretendo. Pero eso debería daros ánimos. Si un principiante como yo puede hacer un script como éste, imaginaos alguien que sepa. ;-)

Observad que hacia la mitad del script hay una llamada misteriosa a un programa que se llama "elige". Bien, ese programa es otro script que contiene:

--------------------------- script "elige" ---------------------------------
#!/bin/sh
#Este script es una chorrada. SEGURO que hay una forma más fácil de extraer
#el quinto argumento de la salida de un ls, pero no la conozco.
# Además, tengo un alias puesto en .bashrc, de tal forma que cuando digo "ls"
# quiero decir, en realidad, "ls -Fhl --color".
echo $5
---------------------------- final del script "elige" ------------------

En fin, la verdad es que no me he molestado mucho en buscar soluciones más elegantes, porque lo cierto es que ésta funciona.

Nota: Existe una solución más elegante, pero no con bash, sino usando el lenguaje awk. Para ello tendríamos que sustituir la linea:

echo "Tamaño: `/opt/progs-usuario/elige $lectura` >> $reg

por esta otra:

echo "Tamaño: `echo $lectura | awk '{print $5}'`" >> $reg

con lo cual ya no hace falta el script "/opt/programas-usuario/elige" ;-).

¿Qué mas queda por hacer?. Pues meter un entrada en /etc/crontab tal que así:

	34 23 * * * root /opt/programas-usuario/asegurar

Con esto, se ejecutaría el script, todos los días a las 23:34 horas, con privilegios "root". El se encargaría de todo, de forma completamente desatendida. Nuestra única preocupación, sería acordarnos, de vez en cuando, de consultar los logs para ver cómo va la cosa. Cuando veamos que se ha hecho una copia completa podemos aprovechar y grabar los CD-RW con las imágenes ISO. Así estaremos protegidos también contra un error físico del disco duro. Claro que, naturalmente, esto también podemos automatizarlo con otro script. :-)

Y ya puestos, también se pueden crear dos alias tal que así:

	alias baksearch='zcat /var/log/asegurados_duro.log.gz | grep -A10 '
        alias bakstatus='zcat /var/log/asegurados_duro.log.gz'

Ahora podemos consultar los log, simplemente tecleando:

	[lacofi@claudia lacofi]$  bakstatus

Con lo que obtendremos una salida coloreada, con el estado actual del backup. Tal que así:

	[lacofi@claudia lacofi]$  bakstatus
[...etc desde el principio de los tiempos...]
    --------------------------
    02/07/2003
    Nivel 14 en el directorio volcado_impar
    tar: Removing leading `/' from member names
    Creado backup en fichero seguridad-2003-07-02-nivel14.tar.gz
    El tamaño del fichero es 18M
    --------------------------
    Se ha reiniciado el Backup
    El antiguo Backup es impar 
    El nuevo Backup es par
    --------------------------
    03/07/2003
    Nivel 0 en el directorio volcado_par
    tar: Removing leading `/' from member names
    Creado backup en fichero seguridad-2003-07-03-nivel0.tar.gz
    El tamaño del fichero es 1021M
    El fichero ha sido partido en /mnt/seguridad/split
    ¡¡Es el momento de usar la grabadora!!
    --------------------------
    04/07/2003
    Nivel 1 en el directorio volcado_par
    tar: Removing leading `/' from member names
    Creado backup en fichero seguridad-2003-07-04-nivel1.tar.gz
    El tamaño del fichero es 31M
    --------------------------
    06/07/2003
    Nivel 2 en el directorio volcado_par
    tar: Removing leading `/' from member names
    Creado backup en fichero seguridad-2003-07-06-nivel2.tar.gz
    El tamaño del fichero es 21M
    --------------------------
    08/07/2003
    Nivel 3 en el directorio volcado_par
    tar: Removing leading `/' from member names
    Creado backup en fichero seguridad-2003-07-08-nivel3.tar.gz
    El tamaño del fichero es 22M
    

O también, podemos teclear:

	[lacofi@claudia lacofi]$  baksearch 01/07/2003

Con lo que obtendremos una salida limitada: solo el backup hecho en esa fecha, si es que el ordenador estaba encendido.

¿Guta?. ;-)


  • Sintaxis HTML 4.01 comprobada
  • Enlaces comprobados


Hecho con gvim * Hecho con CSS