SyntaxHighlighter

miércoles, 25 de marzo de 2015

Buscando y moviendo ficheros a un punto de montaje (script bash)

Supongamos que tenemos una máquina que va almacenando ficheros constantemente, por ejemplo, una máquina que hace copia de seguridad de otras remotamente y almacena los ficheros de forma indefinida. Habrá un momento en el que consumiremos todo el espacio. La solución sería plantearnos una política de borrado de ficheros o mover esos ficheros a unidades fuera del almacenamiento local de la máquina.

Los ficheros podrían ser copiados a otro servidor con rsync o scp, pero en este caso voy suponer que tenemos una unidad de red o un disco USB montado de forma permanente en un directorio de la máquina.

El problema con los puntos de montaje es que el directorio sobre el que se monta el dispositivo siempre está creado y si por algún motivo el dispositivo se desmonta, escribiremos sobre ese mismo directorio pero en el almacenamiento local del servidor. Esto puede hacer que acabemos con el espacio del servidor en una operación de copia fácilmente. Para evitar ese problema el script primero comprobará que efectivamente estamos escribiendo sobre un punto de montaje activo.

El script está programado de manera que se pueda ejecutar desde cron, no recibe parámetros, toda la configuración se realiza modificando las variables de las primeras líneas.  La variable TEXT_IN_FILEPATH, en realidad es una expresión con wildcards que se buscará en el path completo del fichero, por lo que podemos usar cualquier subcadena del path del fichero para realizar la búsqueda.


#!/bin/bash
#This script perform a find command to look for files path in "SOURCE_DIRECTORY" containing "TEXT_IN_FILEPATH" substring RECURSIVELY, then move to a target mount point path.
#The script checks the target directory is a mount point to ensure that the files will be written to an external device.
SOURCE_DIRECTORY=/var/backups/
TARGET_MOUNT_POINT=/media/NAS
TARGET_PATH=/db_backup
TEST_MODE=0
TEXT_IN_FILEPATH='*monthly*bz2'
#********************************************************************************************************************************

MOVED_FILES=0
DIRECTORIES_CREATED=0
if ! mountpoint -q $TARGET_MOUNT_POINT
then
 echo "Not a Mount Point"
 exit 1;
fi

if [ ! -e "$TARGET_MOUNT_POINT$TARGET_PATH" ] 
then
 echo "Target directory not created"
 exit 1;
fi

for i in `find $SOURCE_DIRECTORY -wholename "$TEXT_IN_FILEPATH" -type f` 
do 
# Build target filename: target mount point + target directory inside mountpoint + file without source_directory path begining
 TARGET_FILE=$TARGET_MOUNT_POINT$TARGET_PATH${i/"$SOURCE_DIRECTORY/"//}
 TARGET_FILE_PATH=`dirname $TARGET_FILE`

 
 if [ ! -d $TARGET_FILE_PATH ]
 then
  if [ $TEST_MODE -gt 0 ]
  then
   #TEST MODE
   echo "TEST MODE: mkdir -p $TARGET_FILE_PATH" 
  else
   echo "Creating folder: $TARGET_FILE_PATH"
   mkdir -p $TARGET_FILE_PATH   
   ((DIRECTORIES_CREATED++))
  fi
 fi

 if [ $TEST_MODE -gt 0 ]
 then
  #TEST MODE
  echo "TEST MODE: mv $i $TARGET_FILE_PATH"
 else
  echo "Moving $i"
  mv $i  $TARGET_FILE_PATH
  ((MOVED_FILES++))
 fi
done

echo "Moved backups files summary"
echo "$DIRECTORIES_CREATED directories created"
echo "$MOVED_FILES moved"