Automatización copias de ficheros en FTP mediante EXPECT

Anteriormente publiqué un post con un ejemplo sobre como se podía aumentar la seguridad de nuestro servidor de base de datos MySQL. Mostraba como realizar backups de las diferentes bases de datos de manera individual en ficheros comprimidos.

Para ello utilizamos las herramientas que MySQL pone a nuestra disposición, de manera que realicen el trabajo de la manera que deseamos.

El script que desarrollamos cumplía perfectamente el cometido, aunque debemos ampliar su funcionalidad, ya que realizar los backups en el mismo servidor en el que están alojadas las webs es un grave fallo de seguridad. Por ejemplo, imaginemos que se produce un fallo de hardware en el disco duro del servidor. Ello dejaría inaccesibles tanto las bases de datos como las copias de seguridad.

Hoy explicaré una manera de guardar automáticamente los ficheros comprimidos de la base de datos en un servidor FTP externo. Utilizaremos una herramienta llamada Expect. Permite automatizar aplicaciones de consola interactivas tales como ssh, telnet, y por supuesto la que nos interesa, ftp.

El funcionamiento es muy simple. Básicamente consta de dos instrucciones send = enviar y expect = esperar. Con la primera envía comandos a la aplicación que queremos controlar y espera una respuesta conocida para enviar la siguiente instrucción.

Eg: Enviar el password de FTP.

....
send “mi passwordr”
expect “ftp>”
...
  • La instrucción send envía todos los caracteres que van entre comillas.
  • Utilizamos “\r” para enviar un retorno de carro o pulsación de la tecla Intro.
  • La aplicación FTP escribe en pantalla el texto “ftp>” cada vez que espera mas datos del usuario. Puede darse el caso de que haya un retardo entre los comandos, pero la instrucción expect espera hasta que se recibe la respuesta.

El siguiente código aúna las instrucciones necesarias para enviar por FTP a un servidor externo, con usuario y password, los ficheros alojados en un path de nuestro servidor.

  1. #!/usr/bin/expect
  2.  
  3. set site <direccion_servidor>
  4. set user <usuario>
  5. set pass <password>
  6. set path <ruta/a/los/archivos/>
  7. set files *.bz2
  8.  
  9. spawn ftp $site
  10. expect "Name"
  11.  
  12. send "$user\r"
  13. expect "Password:"
  14.  
  15. send "$pass\r"
  16. expect "ftp>"
  17.  
  18. send "prompt\r"
  19. expect "ftp>"
  20.  
  21. send "bin\r"
  22. expect "ftp>"
  23.  
  24. send "lcd $path\r"
  25. expect "ftp>"
  26.  
  27. send "mput $files\r"
  28. expect -timeout -1 "ftp>"
  29.  
  30. send "bye\r"
  31. expect eof
  32.  

En este código podemos ver como se repiten la secuencia de enviar datos, esperar respuesta, y enviar datos de nuevo.

9 Respuestas a “Automatización copias de ficheros en FTP mediante EXPECT”


  1. 1 Enrique

    Muy sencillo e interesante.
    Sabes com hacer para lo que devuelve el comando enviado con send se guarde en una variable.

    Ejemplo hacer un ls en una máquina remota y guardar la salida en una variable para posteriormente poder pasarle un grep.

    Algo del tipo: set VARIABLE [send -- "ls\r"]

    Lo he probado y no funciona.

    Gracias lo sepas o no.

  2. 2 David García

    Pues la verdad es que no tengo ni idea, he estado haciendo pruebas pero lo mas que he avanzado es crear una variable con el resultado en la maquina remota.

    Sigo investigando a ver que se me ocurre.

  3. 3 Amparo Gonzales

    Muchas gracias David por tu ayuda.
    Sabes como hacer para que coexista en un mismo script el expect y la shell, lo que quiero decir es que necesito que desde teclado se lean unos cuantos parámetros, se guarden en variables y luego se envíen a la máquina con un send. Algo del tipo:
    #!/usr/bin/sh
    #!/usr/local/bin/expect –

    echo “Introduce el nombre del router”
    read RO

    send “$RO
    send — “$RO.\r”

    Lo he probado y no funciona.

    Muchas gracias de antemano.

  4. 4 Jhon

    Voy a tratar de Hacer correr el codigo para lo que necesito…pero mientras tanto en otro sitio habia encontrado esto a alguien le puede servir con imaginacion pueden colocar otras instrucciones…
    echo “ls” | ssh usuario@ip
    y funciona siempre y cuando configuren primero ssh para que no pida usuario ni password si es de ayuda tambien lo dejo como lo hice:

    SSH Y SFTP SIN CLAVE EN UBUNTU 7.04

    1. Primero generamos nuestra llave pública y privada en el cliente
    con el usuario que queremos que haga la conexion:

    ssh-keygen -t rsa

    Nota: Donde nos pide el Directorio damos enter y donde nos pide la clave tambien damos enter para que quede en blanco y no nos pida nada cuando nos vamos a conectar

    2. Luego hacemos:
    $ ssh-copy-id usuario@servidor.remoto
    Eso nos copia la clave publica al servidor que queremos acceder sin clave Falta verifiacar que ya este…y listo ya podemos acceder con sftp o con ssh sin que nos pida usuario ni password

    si hay errores…por favor corregirlos…

    Saludos

  5. 5 David García

    Es decir que solamente puedes conectar desde una ip en concreto entiendo no?

  6. 6 Mauro

    crea primero un archivo .sh comun #!/usr/bin/sh
    ejecuta los comandos que quieras y de aca como leer las variables que te van a ingresar por teclado y luego invoca al archivo #!/usr/local/bin/expect – pasandole las variables como parametros

    eje:
    —-conectar.sh—-
    #!/bin/bash
    #Pido el ingreso de un usuario
    echo -n “introducir usuario: ”
    read usuario
    #Pido la clave
    echo -n “introducir password: ”
    read clave
    #ahora llamamos al archivo que contiene el expect pasando x parametros el usuario y la clave
    ./conectar_expect $usuario $clave

    —-conectar_expect—-
    #!/usr/local/bin/expect –
    set usuario [lindex $argv 0]
    set password [lindex $argv 1]
    spawn ssh $usuario@ip_servidor
    expect “Password:”
    #send “$password\r”
    expect eof

  7. 7 pedro torres

    Necesito utilizar FTP para multile archivos. Estoy generando bien el proceso PERO no me cambia el nombre con que necesito quede el servidor:
    el comando que uso es:
    MPUT ‘CLBD.AB.FRM06.BUSCA*’ BUSCA*.DAT (REPLACE
    +++++++++++
    Pero, el archivo lo deja en el serividor entre apostrofes y el mismo que tiene en HOST, en lugar de BUSCA*.DAT
    Gracias por la ayuda

  8. 8 Nin

    Muchísimas gracias por el comentario. El artículo es breve, sencillo y muy efectivo, es precisamente lo que estaba buscando desde hace semanas.

    Sólo agradecerte el esfuerzo de compartirlo con nosotros.

    Un abrazo !

    Nin

  9. 9 David García

    Muchas gracias! A mandar! ;)

Añade un Comentario