Programa para sincronizar directorios en servidor remoto
«CopiSec» programa de sincronización remota con rsync
Vamos a ver un script que nos permitirá hacer copias de seguridad en un servidor remoto a través de la red. Podemos tener un servidor dedicado a contener copias de seguridad de los demás equipos que tengamos en la red. Lo hacemos con «rsync», que nos permite sincronizar eficientemente ficheros y directorios. Podríamos utilizar el comando «cp» o «scp», pero «rsync» es más rápido al hacer copias incrementales de estos y no los ficheros completos.
En Rsync «remote sync», puedes ver con detalle el uso del comando.
En una infraestructura en red, lo podemos tener automatizado con un script que sea llamado, programándolo con «crontab», para que realice las copias, o mejor, sincronice los directorios de los equipos cliente en el servidor, manteniendo, así, una copia de estos actualizada, desde la que recuperar los datos en caso de desastre.
Hoy, veremos un programa shell script, que podemos llevar en un dispositivo extraíble para utilizarlo donde necesitemos. Para ello, nos solicitará los datos que necesita para hacer su trabajo: la IP del servidor, la ruta del directorio origen, la del de destino y la contraseña de logeo en el servidor.
Utilizaremos una herramienta para la creación de cuadros de diálogo y que nos solicite estos datos. Esta herramienta es «zenity», que utiliza la librería GTK y que se integra perfectamente en los entornos de escritorio GNOME, KDE, Mate, Cinnamon, etc…
Sumario
- Consideraciones previas
- Análisis del código
- Funcionamiento del programa
- Código del programa
Consideraciones previas
Este programa puede ser muy práctico para llevarlo en un USB y utilizarlo donde necesitemos realizar la copia. Para ello, en vez de pasarle los argumentos en el propio script, con cuadros de dialogo, iremos solicitando estos. De esta manera no tendremos que modificar el código cada vez que lo vayamos a utilizar.
Estos cuadros de diálogo los creamos con «zenity», obteniendo una interfaz gráfica de ventanas, que facilitará su uso a aquellos que se lleven peor con la interfaz de linea de comandos (CLI).
Para pasar el argumento de la contraseña del servidor, utilizamos la herramienta «sshpass», con el fin de securizar más el proceso, ya que siempre que transmitimos datos a través de la red, siempre hay riesgo de captura de los datos.
Vamos a ver el código y lo analizamos por partes. Luego aportaré el código completo para que solo tengas que copiar y pegar.
Análisis del código
Para establecer las variables que constituirán los argumentos, usamos una interfaz de ventanas cómoda y facil de usar. En primer lugar nos solicita la fecha de realización de la copia.
FECHA=$(zenity --calendar \ --title="weblinus.com CopiSec" \ --text="Elige la fecha de la copia") ans=$? if [ $ans -eq 0 ] then echo "La fecha de la copia es: ${FECHA}" else echo "Adios $USER" exit 1 fi echo "Copia de seguridad realizada el: $FECHA" >>~/copia.log
Añadimos la fecha al fichero «copia.log». Así sabremos cuando se han hecho las copias.
En el código, para que nos solicite los demás argumentos, incluímos la posiblidad de cerrar el programa, si carecemos de alguno de los datos. Vemos el argumento IP del servidor
IPSERVER=$(zenity --forms \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Introduce la IP del servidor." \ --add-entry="IPServer") ans=$? if [ $ans -eq 0 ] then echo "La IP del servidor es: ${IPSERVER}" else echo "Adios $USER" exit 2 fi
Para determinar el origen de los datos, establecemos la variable $RUTA utilizando –file-selection
RUTA=$(zenity --file-selection \ --title="weblinus.com CopiSec" \ --height=200 \ --width=100 \ --text="Selecciona un directorio origen de la copia:" \ --directory) ans=$? if [ $ans -eq 0 ] then echo "Has elegido el directorio: ${RUTA}" else echo "Adios $USER" exit 3 fi
Y para el destino de los datos, la ruta en el servidor, con –entry,
DESTINO=$(zenity --entry \ --title="weblinus.com CopiSec" \ --width=250 \ --height=200 \ --cancel-label="Salir" \ --text="Introduce la ruta al directorio destino del servidor." \ --add-entry="DESTINO") ans=$? if [ $ans -eq 0 ] then echo "Has elegido el directorio: ${DESTINO}" else echo "Adios $USER" exit 4 fi
Para la contraseña utilizamos –password, que ocultará esta mientras la introducimos
PASS=$(zenity --password \ --title="weblinus.com CopiSec" \ --width=250 \ --ok-label="Aceptar" \ --cancel-label="Salir" \ --text="Introduce la contraseña de logeo en el servidor:") ans=$? if [ $ans -eq 0 ] then echo "La contraseña es: ${PASS}" else echo "Adios $USER" exit 5 fi
Para poder pasar el «password» al comando, sin incluirlo en el código, utilizamos «sshpass», pero crearemos un fichero con la contraseña, del que lo leerá el comando. Una vez establecida la conexión, borraremos el fichero. Lo creamos y le damos permisos.
echo $PASS >>pass_file chmod 0700 pass_file
Luego tenemos que comprobar que el servidor está disponible y escuchando.
zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Comprobando que el servidor está disponible" ping -c 1 $IPSERVER >/dev/null if [ $? -ne 0 ] then zenity --error \ --title="weblinus.com CopiSec" \ --width=250 \ --text="El servidor no está disponible" exit 2 else zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="El servidor está disponible para hacer la copia" fi
Y ejecutamos el programa principal, creando los ficheros de log, para comprobar el resultado y los posibles errores.
sshpass -f pass_file rsync -avi --stats --progress $RUTA $USER@$IPSERVER:$DESTINO/$FECHA >>~/copia.log 2>>~/errores_copia.log
El siguiente código es para mostrar el resultado de la copia y los errores. Encontrarás, en el mismo código, comentarios para interpretarlo.
Finalmente nos preguntará si queremos seguir haciendo copias o salir del programa.
Funcionamiento del programa
Veamos, con capturas, como funciona el programa.
Para ejecutar el programa, lo primero será otorgar permisos de ejecución
chmod +x CopiSec.sh
Lo ejecutamos
./CopiSec.sh
Seleccionamos la fecha de la copia y Aceptar. Si cancelamos saldrá del programa.
Introducimos la IP del servidor
Nos abre el navegador de ficheros. Buscamos el directorio o fichero, lo seleccionamos y Aceptar.
Indicamos la ruta destino de la copia
Y la contraseña de logeo en el servidor
Nos avisa de que está comprobando si el servidor está disponible. Aceptamos y seguimos.
En este caso está disponible. Aceptamos.
Si no lo estuviera nos avisaría y saldría del programa
Y nos dice que todas las actualizaciones están terminadas.
Si hubiese habido errores, nos lo indicaría ahora, mostrando la ruta al fichero de log. No es el caso.
La copia ha sido realizada con exito. Nos indica la ruta al fichero de log para comprobar el proceso.
Y hemos terminado la copia. Todos los ficheros sincronizados.
Finalmente nos pregunta si queremos seguir hacer más copias.
Si contestamos que sí, se reinicia el programa.
Veamos el resultado en el servidor.
Volvemos al cliente y consultamos el contenido del fichero de log.
Añadimos el «Directorio2» al «Directorio1» y volvemos a ejecutar el programa
En el fichero de log, vemos que ha trasferido «Directorio2» y todo su contenido
Y en el servidor comprobamos que todo es correcto.
Código del programa
Aquí tienes el código completo. Solo tienes que copiar y pegar, y darle permisos de ejecución.
#!/bin/sh # Este programa ha sido creado por Francisco Javier Izquierdo Hidalgo. # Este programa es software libre; puedes redistribuirlo y / o # modificarlo bajo los términos de la Licencia Pública General de GNU # publicado por la Free Software Foundation; ya sea la versión 2 # de la Licencia, o (a su elección) cualquier versión posterior. # Este programa se distribuye con la esperanza de que sea útil, # pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de # COMERCIABILIDAD o APTITUD PARA UN PROPÓSITO EN PARTICULAR. Ver el # GNU General Public License para más detalles. #Asignamos valores a las variables FECHA=$(zenity --calendar \ --title="weblinus.com CopiSec" \ --text="Elige la fecha de la copia") ans=$? if [ $ans -eq 0 ] then echo "La fecha de la copia es: ${FECHA}" else echo "Adios $USER" exit 1 fi echo "Copia de seguridad realizada el: $FECHA" >>~/copia.log IPSERVER=$(zenity --forms \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Introduce la IP del servidor." \ --add-entry="IPServer") ans=$? if [ $ans -eq 0 ] then echo "La IP del servidor es: ${IPSERVER}" else echo "Adios $USER" exit 2 fi RUTA=$(zenity --file-selection \ --title="weblinus.com CopiSec" \ --height=200 \ --width=100 \ --text="Selecciona el directorio origen de la copia:" \ --directory) ans=$? if [ $ans -eq 0 ] then echo "Has elegido el directorio: ${RUTA}" else echo "Adios $USER" exit 3 fi DESTINO=$(zenity --entry \ --title="weblinus.com CopiSec" \ --width=250 \ --height=200 \ --cancel-label="Salir" \ --text="Introduce la ruta al directorio destino del servidor." \ --add-entry="DESTINO") ans=$? if [ $ans -eq 0 ] then echo "Has elegido el directorio: ${DESTINO}" else echo "Adios $USER" exit 4 fi PASS=$(zenity --password \ --title="weblinus.com CopiSec" \ --width=250 \ --ok-label="Aceptar" \ --cancel-label="Salir" \ --text="Introduce la contraseña de logeo en el servidor:") ans=$? if [ $ans -eq 0 ] then echo "La contraseña es: ${PASS}" else echo "Adios $USER" exit 5 fi #Creamos fichero con la contraseña para pasarlo al comando rsync y le damos permisos echo $PASS >>pass_file chmod 0700 pass_file #Comprobamos que el servidor está accesible zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Comprobando que el servidor esta disponible" ping -c 1 $IPSERVER >/dev/null if [ $? -ne 0 ] then zenity --error \ --title="weblinus.com CopiSec" \ --width=250 \ --text="El servidor no está disponible" exit 2 else zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="El servidor está disponible para hacer la copia" fi #Ejecutamos el comando con los valores establecidos para las variables y creamos los ficheros de log sshpass -f pass_file rsync -avi --stats --progress $RUTA $USER@$IPSERVER:$DESTINO >>~/copia.log 2>>~/errores_copia.log #Borramos el fichero con la contraseña rm pass_file #Mostramos proceso de copia PROCESO=$(cat ~/copia.log) zenity --info \ --title="weblinus.com CopiSec" \ --height=200 \ --width=250 \ --text="$PROCESO" #Comprobamos si ha habido errores ERRORES=$(cat ~/errores_copia.log) echo $ERRORES >/dev/null if [ $? -eq 0 ] then zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="No ha habido errores en el proceso" rm ~/errores_copia.log else zenity --error \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Ha habido <b>errores</b>. Revisa el fichero ~/errores_copia.log" #Mostramos los errores zenity --info \ --title="Mensage de errores" \ --height=200 \ --width=250 \ --text="$ERRORES" fi #Nos Informa de que se ha completado el proceso con exito COPIA=$(cat ~/copia.log) zenity --info \ --title="weblinus.com CopiSec" \ --width=250 \ --text="Copia realizada con exito, consulta el fichero ~/copia.log para más infoemación" #Mostramos la información del proceso zenity --info \ --title="Ficheros sincronizados" \ --height=200 \ --width=250 \ --text="$COPIA" #Preguntamos si queremos continuar zenity --question \ --title="weblinus.com CopiSec" \ --width=250 \ --text="¿Quieres seguir haciendo copias?" ans=$? if [ $ans -eq 0 ] then echo "Continuamos...." ./ScriptCpSegZenity.sh else echo "Programa finalizado" fi exit 0
Espero que te sea de utilidad.
Si tienes algún comentario que hacer sobre este artículo, al pie del post tienes un formulario para hacerlo.
Si quieres contactar conmigo por cualquier otro asunto relacionado con el sitio, en la página de contacto, tienes un formulario más adecuado.
Y para suscribirte y recibir las novedades publicadas, tienes un enlace en el pie de la página o desde aquí mismo.
Gracias Javier. Buen trabajo
Gracias por tu visita Barto
Gracias Javier. Una herramienta muy útil, con muchas posibilidades. Estoy seguro que la voy a utilizar enseguida.
Me alegro. Gracias por tu visita Josevi