Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Script con el prompt de windows

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Lun Jul 28, 2008 5:26 am
miguialberto
Perlero Nuevo
Perlero Nuevo
Registrado: 28 Jul 2008
Mensajes: 28
Script con el prompt de windows Responder citando

Hola,

A ver si alguien me puede ayudar con esta duda que tengo a la hora de escribir un script:

Tengo una base de datos Sybase en la que quiero realizar unas operaciones cada noche (borrado de datos en ciertas tablas). Lo que quiero es ejecutar un script en Perl para que cada noche me realice este trabajo. La manera de realizar esto de manera manual es abrir la shell de Windows (cmd.exe) y alli realizar una llamada a la BD mediante "isql -Login y _pass". En este momento se ejecuta la consola de la BD y allí se puede ordenar lo que se desee.

Estoy intentando escribir el script, pero ando bastante perdido. He probado con System() y Exec() pero solo consigo que se ejecute la shell de Windows (ejecuto cmd.exe). Lo que me falta es la manera de poder comunicarme con la shell, para poder mandarle comandos y yo poder recibir las respuestas que me da para poder procesarlas.

No se si debo usar alguna librería de Win32:: ?? o se puede hacer esto como si se tratara de un fichero y escribir y leer directamente... ¡no sé por dónde empezar a mirar!

Muchas gracias de antemano!

Ciao
Mensaje Lun Jul 28, 2008 5:56 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4102
Ubicación: Valladolid, España
Responder citando

Bienvenido a los foros de Perl en Español, miguialberto.

¿No es posible pedirle a isql que ejecute un fichero sql externo?

Es decir: tu, desde Perl, ejecutas un script que lo que hace es llamar a isql con los parámetros de login y contraseña Y un fichero sql a ejecutar.

Estaba mirando para ver si había algún driver de Sybase para Windows, pero me parece que esa base de datos ha caído en el olvido, y hace mucho que no sale una versión estable (al menos para Windows).

En estos foros hay algunos hilos al respecto de Sybase. Usa el sistema de búsqueda.
Mensaje Lun Jul 28, 2008 6:12 am
miguialberto
Perlero Nuevo
Perlero Nuevo
Registrado: 28 Jul 2008
Mensajes: 28
Responder citando

Hola,

Muchas gracias por la respuesta y por la rapidez. Voy a intentar mirar lo que me has dicho a ver si encuentro algún "atajo" con Sybase.

De todas formas me gustaría saber cómo se podría hacer en Perl lo que preguntaba anteriormente, el mantener una comunicación bidireccional con la shell o prompt de Windows. ¡Me vale con que me mostréis el camino! (es con fichero redireccionando la entrada, o system() o fork(), o librerías especiales...).

Gracias de nuevo.

Ciao
Mensaje Lun Jul 28, 2008 7:05 am
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
Responder citando

Hola migialberto:

Igualmente te doy la bienvenida a los foros de Perl en Español.

Para lo que quieras hay varios módulos en CPAN y quizá el que te recomendaría yo para que comiences es el IO::Prompt.

Saludos
Mensaje Lun Jul 28, 2008 7:31 am
miguialberto
Perlero Nuevo
Perlero Nuevo
Registrado: 28 Jul 2008
Mensajes: 28
Responder citando

Gracias, lo miraré a ver si me sirve.

De todas formas, tal como comento explorer, en Sybase existe una forma sencilla de cargar un fichero que contenga instrucciones para la BD (select * from table_x; go). Simplemente, cuando se abre la consola con el comando "isql" además de pasarle el User y el pass se le puede pasar un archivo de lectura y otro de salida. El archivo input o de entrada se pone después de poner "-i" y el de output o salida después de poner "-o".

Por ejemplo, para el user "Guess" con password "secret" y con un fichero llamado "Script_Sybase" que está en "C:/" y que los resultados queremos los deje en "C:/result", tendríamos que escribir:

Código:
isql -U Guess -P secret -i c:/Script_Sybase -o C:/result


También he visto que se puede acceder a la BD a través del puerto que esté escuchando... ¡ya os contaré en este post lo que vaya averiguando!

Saludos y gracias de nuevo.
Mensaje Lun Jul 28, 2008 8:01 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4102
Ubicación: Valladolid, España
Responder citando

Pues entonces, solo te queda meter esa línea en un system().

Atención: si pones algún carácter '\', debes escaparlo (cosas de Windows).
Mensaje Mar Jul 29, 2008 2:57 am
Jenda
Perlero Frecuente
Perlero Frecuente
Registrado: 29 Oct 2007
Mensajes: 105
Ubicación: Praga, Republica Checa
Responder citando

Otra opción es olvidar isql y conectar a la base de datos directamente desde Perl usando DBI y DBD::ODBC. Y mandar los queries a la BD desde el script Perl.
Mensaje Mar Jul 29, 2008 3:38 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4102
Ubicación: Valladolid, España
Responder citando

¡Anda, mira! ¡Pero si eso es justo lo que he usado todo el año pasado, y no me acordaba!

Yo usaba eso con la base de datos Informix. Aunque sí que existe el driver DBD::Informix (servido por la propia IBM), en el lugar de trabajo donde estaba usábamos la pasarela ODBC. Un poco lenta (sobre todo cuando haces peticiones de decenas de millones de registros) pero al menos daba una solución conocida.
Mensaje Mar Jul 29, 2008 4:19 am
miguialberto
Perlero Nuevo
Perlero Nuevo
Registrado: 28 Jul 2008
Mensajes: 28
Responder citando

¡Gracias por dar más posibilidades!

De momento me he creado un programa que escribe todas las instrucciones que quiero ejecutar en Sybase en un archivo y luego llamo al comando de "isql" que escribe en el anterior post. Por si le interesa a alguien, aquí dejo el código:

Perl:
use Date::Calc qw( Time_to_Date )#($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);

open (INPUT_FILE, '>c:/data.txt');

my @current_date = Time_to_Date(time);
my $db_command = "use pubs2\ngo\nselect *\nfrom authors\ngo\nquit";

print INPUT_FILE $db_command;

close (INPUT_FILE);

my $output_file_path = "c:/Log_".$current_date[2]."_".$current_date[1]."_".$current_date[0].".txt";
system('isql -U sa -P -i c:/data.txt -o '.$output_file_path);


El script guarda la consulta en C:/data.txt. A este archivo se le pasa como parámetro a Sybase cuando se inicializa. Los resultados los deja en C:/Log_<fecha_actual>. Además, este script se puede ejecutar en un BD Sybase que tenga instalada la BD de ejemplo "pubs2", que viene por defecto con la documentación.

¡Gracias de nuevo por la ayuda!

Ciao
Mensaje Mar Jul 29, 2008 5:31 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4102
Ubicación: Valladolid, España
Responder citando

Otra posibilidad (no probada):

Perl:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $fichero_entrada = 'C:/data.txt';
open (INPUT_FILE, ">$fichero_entrada");
print INPUT_FILE join "\n", 'use pubs2', 'go', 'select *', 'from authors', 'go', 'quit';
close INPUT_FILE;

my @current_date     = localtime();
my ($dia,$mes,$anno) = ($current_date[3], $current_date[4]++, $current_date[5]+1900);

my $fichero_salida = sprintf "C:/Log_%02d_%02d_%04d.txt ", $dia, $mes, $anno;

system("isql -U sa -P -i $fichero_entrada -o $fichero_salida");

__END__
Te ahorras un módulo.

Un detalle: yo preferiría cambiar el orden de la fecha, para que sea en el orden año, mes, día. Así:
Perl:
my $fichero_salida = sprintf "C:/Log_%04d_%02d_%02d.txt ", $anno, $mes, $dia;

De esa forma, los ficheros podrán ser ordenados temporalmente por su nombre, independientemente de su fecha de modificación, algo muy útil cuando esa fecha se pierde al mover los ficheros de un sistema de ficheros a otro.
Mensaje Mar Jul 29, 2008 6:51 am
miguialberto
Perlero Nuevo
Perlero Nuevo
Registrado: 28 Jul 2008
Mensajes: 28
Responder citando

¡Gracias de nuevo!

Ya te he copiado las "actualizaciones" Smile

Queda bastante más limpio de esta manera. Lo del módulo la verdad es que ni lo había pensado porque como nunca había utilizado ninguno (llevo dos días con Perl) ¡pensé que sería una buena manera de ponerlo en practica!... pero vamos, ¡mejor así!

¡Gracias & Ciao!
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group