Ver Mensaje Individual
  #5 (permalink)  
Antiguo 16/07/2003, 15:33
leonardop
 
Fecha de Ingreso: julio-2003
Mensajes: 165
Antigüedad: 21 años, 8 meses
Puntos: 1
Hola de nuevo,

Creo que ya entiendo cuál es tu problema. Sucede que el comando pg_dump al ser llamado con la bandera `-u' convierte la aplicación en un programa "interactivo", es decir, que espera la respuesta del usuario desde la sesión de terminal.

Cuando ejecutas tu programa Perl en la línea de comandos, seguramente recibirás una respuesta como:

Código:
$ ./pg_cgi.pl 
User name: mi_usuario
Password:
En donde tu escribes manualmente los valores de nombre de usuario y contraseña. Cuando transladas eso al entorno CGI, las cosas ya no van a funcionar de igual modo. El programa Perl no tiene en este punto un modo de transmitirle al proceso pg_dump esa información que tu ingresas manualmente en la línea de comandos.

Este es un problema un poco complejo, ya que tratar de emular o automatizar la entrada estándar de un proceso separado desde Perl tiene una serie de inconvenientes. Los búferes de Unix suelen arruinarlo todo cuando se intentan soluciones simples, y por lo general tener que recurrir a tanto complique para algo tan "simple" es señal de que deben haber otras formas de resolver el problema.

Así que te puedo dar dos recomendaciones, primero, intenta evitar el parámetro `-u' del comando pg_dump. No sé qué versión de postgresql tienes, y tengo entendido que el comando pg_dump ha modificado un poco el comportamiento de sus banderas (cosa que depende de la versión que tengas). Es posible que en tu caso el comando acepte la bandera `-U' (en mayúscula), la cual sirve para especificar directamente el nombre del usuario para acceder a la base de datos (al menos en la versión 7.3.2 de postgres, que yo tengo). En ese caso, es posible que te sirva algo como esto:

Código:
    system("pg_dump -U mi_usuario vacunas4 > vacunas4.pgdump");
Si esto no funciona, otro camino podría ser buscar medios para automatizar este programa interactivo. Existe una aplicación popular que hace exactamente eso. Se llama `Expect':

http://expect.nist.gov/

Muy posiblemente si tienes los CDs de RedHat, o dispones de cualquier otro recurso de instalación del sistema, encuentres allí rpms para este paquete y puedas instalarlo de forma simple. Una vez tengas instalado el programa expect, puedes usarlo directamente como intérprete para tu aplicación orientada a CGI, la cual hará de intermediario entre el servidor web y el comando pg_dump. El comando `expect' básicamente tiene la capacidad de ejecutar comandos que son una combinación del lenguaje Tk y la sintaxis propia de comandos Expect. En la documentación de expect encontrarás más información.

Por ejemplo, podrías escribir un script con este aspecto:

Código:
#! /usr/bin/expect -f

# No direccionar el resultado de las interacciones a stdout
log_user 0

# Iniciar el proceso externo. Notese que la redireccion a un archivo
# de salida se realiza mas adelante
spawn pg_dump -u vacunas4

# Se emula el ingreso normal de los datos de nombre de usuario y
# contrasenya
expect "User name: "
send "mi_usuario\r"
expect "Password: "
send "mi_contrasenya\r"

# Se define el archivo de salida del comando pg_dump
set salida [open "/usr/local/pgsql/data/vacunas4.pgdump" w]

# Se define un tiempo de espera comodo
set timeout 30

# Leer la salida del comando pg_dump y almacenarla en el archivo de
# salida
expect {
    -re "(.*)\n" {
        puts $salida "$expect_out(buffer)\n"
        exp_continue
    }
}

# Imprimir las cabeceras HTTP y el contenido de la pagina web
puts "Content-type: text/html\n\n";

puts "<HTML><HEAD><TITLE></TITLE></HEAD>\n\
<BODY>\n\
<H2 align=center>LA BASE DE DATOS HA SIDO SALVADA CORRECTAMENTE</H2>\n\
<BR><BR><BR><BR><A href=\"javascript:close()\">Cerrar ventana</A><BR>\n\
<A HREF=\"javascript:history.back()\"> Volver atr\x{FFFD} </A><BR>\n\
<A HREF=\"http://10.170.136.111/primera.htm\"> Salir </A>\n\
<BR><A HREF=\"http://10.170.136.111/secret/admin2.htm\">\n\
Volver al menu de administrador</A>\n\
</BODY>\n\
</HTML>\n"
El previo script, como cualquier otra aplicación para CGI, debe tener permisos de ejecución y una extensión válida para que el servidor web reconozca que es CGI.

Si no deseas o no puedes instalar este paquete, hay otra opción y es mediante una librería de Perl que se llama precisamente Expect.pm. El propósito de esta librería es muy similar al paquete con el mismo nombre, y es 100% perl. Puedes encontrarla en CPAN, el repositorio más famoso de librerías de Perl que se conoce. Si tienes experiencia instalando nuevas librerías desde CPAN, quizás quieras probar este método.

Espero que encuentres la solución definitiva a tu problema. Un saludo.