Dom Jun 08, 2008 12:47 am
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
| Consulta, ¿hay alguna forma sencilla de pasar el "-s" a argumento? Así puedo controlar mejor lo que ingresa el usuario. |
|
|
|
Dom Jun 08, 2008 9:35 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
| Sí, lo puedes sacar del código y cuando quieras, lo agregas como primer argumento del programa, desde la línea de comandos, por ejemplo. |
|

Dom Jun 08, 2008 7:16 pm
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
Explorer,
Una consulta estoy tratando de hacer, lo siguiente, si el ARG es igual a "-name" que ejecute la función de esa opción, pero no sé cómo hacer ese if no me sale.
| Perl: | #!/usr/bin/perl
## Comprobacion del MODULO
BEGIN {
eval "use XML::Simple";
if ( $@ ) {
warn "Error al cargar el modulo: XML::Simple\n"
. "Instalar Modulo:\n"
. "\t\tcpan\n"
. "\t\tcpan> install XML::Simple\n";
exit ();
}
}
use XML:: Simple;
use strict;
## Ayuda del sistema
if ( @ARGV != 1 ) {
die "\nUse: $0 -opcion\n\n"
. " -name=pc Busqueda por nombre del host\n"
. " -notes=test Busqueda por nota\n"
. " -ip=1.1.1.1 Busqueda por direccion ip\n"
. " -url=https://10.0.0.1 Busqueda por url\n\n"
;
}
## Variable globales para las busquedas
our $name;
our $notes;
our $ip;
our $url;
## Definicion de variables
my $info = XMLin ("kk.xml", KeyAttr => 1, ForceArray => [ 'user' ]);
my $host = $name || '.+';
my $notes = $notes || '.+';
my $ip = $ip || '.+';
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $pc-> {name } !~ /^ $host$/;
next if $pc-> {notes } !~ /^ $notes$/;
next if $pc-> {ip } !~ /^ $ip$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t$user->{name} : $user->{password}\n";
}
} |
|
|

Lun Jun 09, 2008 1:17 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
Varias cosas:
* Si colocas el '-s' en la primera línea del programa, Perl colocará el valor de los argumentos pasados por el usuario en las variables globales del mismo nombre, tal como te indiqué antes
* Después, dentro del programa, no está claro que el usuario pueda buscar por una, más de una, o todas las opciones. O si es obligatorio buscar por todas. Tal como lo tienes indicado en el if del @ARGV, todas las opciones son obligatorias. Pero yo creo que no es eso lo que quieres hacer, sino que sean todos opcionales
* En caso de ser opciones, hay que modificar un poco las condiciones, para tenerlas en cuenta solo en el caso de haber sido puestas.
Con esas modificaciones, el programa queda así:
| Perl: | #!/usr/bin/perl -s
use strict;
use warnings;
##
BEGIN {
eval "use XML::Simple";
if ( $@ ) {
warn "Error al cargar el módulo: XML::Simple\n"
. "Instalar Módulo:\n"
. "\t\tcpan XML::Simple\n\n";
exit();
}
}
our $name;
our $notes;
our $ip;
our $url;
## Ayuda del sistema
if ( ! @ARGV ) {
die "Uso: $0 [-name|-notes|-ip|-url] <fichero xml>\n"
. "\t-name=pc Búsqueda por nombre del host\n"
. "\t-notes=test Búsqueda por nota\n"
. "\t-ip=1.1.1.1 Búsqueda por dirección ip\n"
. "\t-url=https://10.0.0.1 Búsqueda por url\n\n"
;
}
my $info = XMLin ($ARGV[0], KeyAttr => 1, ForceArray => [ 'user' ]);
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $name and $pc-> {name } !~ /^ $name$/;
next if $notes and $pc-> {notes } !~ /^ $notes$/;
next if $ip and $pc-> {ip } !~ /^ $ip$/;
next if $url and $pc-> {url } !~ /^ $url$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t$user->{name} : $user->{date}\n";
}
} | Notas:
* Hemos quitado un 'use' que sobraba: el que estaba dentro del BEGIN es suficiente
* El if del @ARGV se modifica para que se ejecute en el caso de que no se le hayan pasado argumentos al programa. Como mínimo, hay que pasarle el nombre del fichero xml a procesar
* Dentro del bucle, modificamos los if para que solo funcionen en caso de haber sido indicadas como argumentos
Ahora ya se puede invocar el programa de varias formas:
| Código: |
explorer@joaquin:~/Documents/Desarrollo> ./kk.pl kk.xml
marcos => https://10.1.1.1 (10.1.1.1)
admin : 20080101
root : 20080101
marcos2 => https://10.2.2.2 (10.2.2.2)
root : 20080102
explorer@joaquin:~/Documents/Desarrollo> ./kk.pl -name=marcos kk.xml
marcos => https://10.1.1.1 (10.1.1.1)
admin : 20080101
root : 20080101
explorer@joaquin:~/Documents/Desarrollo> ./kk.pl -ip=10.2.2.2 kk.xml
marcos2 => https://10.2.2.2 (10.2.2.2)
root : 20080102
explorer@joaquin:~/Documents/Desarrollo> ./kk.pl -url=https://10.2.2.2 kk.xml
marcos2 => https://10.2.2.2 (10.2.2.2)
root : 20080102
explorer@joaquin:~/Documents/Desarrollo> ./kk.pl -notes=test kk.xml
marcos => https://10.1.1.1 (10.1.1.1)
admin : 20080101
root : 20080101 |
Se puede hacer la siguiente variación: en el caso de que el fichero xml sea siempre el mismo, entonces lo dejamos indicado en el programa, como teníamos antes:
| Perl: | my $info = XMLin('kk.xml', KeyAttr => 1, ForceArray => [ 'user' ]); | Entonces tenemos que modificar el primer if:
| Perl: | our $h;
if ( $h ) {
die "Uso: $0 [-h|-name|-notes|-ip|-url] <fichero xml>\n"
. "\t-name=pc Búsqueda por nombre del host\n"
. "\t-notes=test Búsqueda por nota\n"
. "\t-ip=1.1.1.1 Búsqueda por dirección ip\n"
. "\t-url=https://10.0.0.1 Búsqueda por url\n\n"
;
} | Así, si el usuario ejecuta el programa sin más, vuelca todo el fichero. Si indica '-h', sale la ayuda y termina.
Pero si quisiéramos que el usuario ponga al menos una opción de filtrado, deberíamos ponerlo también en el primer if:
| Perl: | if ( ! $name and ! $notes and ! $ip and ! $url ) {
die "Uso: $0 [-name|-notes|-ip|-url] <fichero xml>\n"
. "\t-name=pc Búsqueda por nombre del host\n"
. "\t-notes=test Búsqueda por nota\n"
. "\t-ip=1.1.1.1 Búsqueda por dirección ip\n"
. "\t-url=https://10.0.0.1 Búsqueda por url\n\n"
;
} |
Ultima edición por explorer el Lun Jun 09, 2008 10:57 am, editado 1 vez |
|

Lun Jun 09, 2008 9:46 am
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
| Muchísimas gracias |
|
Lun Jun 09, 2008 11:00 am
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
Te hago una consulta. ¿Este módulo tiene para escribir en el XML?, porque mi idea es más adelante poder ingresar más datos al XML desde la consola.
EDIT:
Ahí lo encontré:
http://search.cpan.org/dist/XML-Writer/Writer.pm
Voy a ver si puedo adaptarlo  |
|
Lun Jun 09, 2008 12:44 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
| Puedes escribirlo con la función XMLout() del mismo módulo XML::Simple. |
|
Lun Jun 09, 2008 1:54 pm
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
Lun Jun 09, 2008 2:47 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
| Hay un montón de ejemplos en estos foros. Busca por las palabras XML y Simple. Activa la opción "Buscar todas las palabras". También puedes restringir la búsqueda a los mensajes escritor por mí (pon 'explorer' en la caja de autores). Puedes reducir aún más la búsqueda, agregando la palabra XMLout. Salen 6 hilos, incluido este. |
|

Lun Jun 09, 2008 3:51 pm
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
Consulta, me quedó el siguiente script.
| Perl: | #!/usr/bin/perl -s
use strict;
use warnings;
##
BEGIN {
eval "use XML::Simple";
if ( $@ ) {
warn "Error al cargar el modulo: XML::Simple\n"
. "Instalar Modulo:\n"
. "\t\tcpan XML::Simple\n\n";
exit();
}
}
our $name;
our $notes;
our $ip;
our $url;
## Ayuda del sistema
if ( ! $name and ! $notes and ! $ip and ! $url ) {
die "Uso: $0 [-name|-notes|-ip|-url]\n"
. "\t-name=pc Busqueda por nombre del host\n"
. "\t-notes=test Busqueda por nota\n"
. "\t-ip=1.1.1.1 Busqueda por direccion IP\n"
. "\t-url=https://10.0.0.1 Busqueda por url\n\n"
;
}
my $info = XMLin ('kk.xml', KeyAttr => 1, ForceArray => [ 'user' ]);
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $name and $pc-> {name } !~ /^ $name$/;
next if $notes and $pc-> {notes } !~ /^ $notes$/;
next if $ip and $pc-> {ip } !~ /^ $ip$/;
next if $url and $pc-> {url } !~ /^ $url$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t$user->{name} : $user->{password}\n";
}
}
sub crear {
my $xml = << "END_OF_XML";
<pc>
<name>marcos3</name>
<url>https:// 10. 1. 1. 1</url>
<ip>10. 3. 3. 3.</ip>
<user name= "admin"> <password>4444</password> <date>20080333</date></user>
<notes>culito</notes>
</pc>
END_OF_XML
open $fh, q{>>:encoding (iso- 8859- 1)}, 'kk.xml';
print $fh $xml;
close $fh;
} |
Ahora me gustaría hacer que cuando alguien pone:
| Código: |
| ./prueba.pl -crear |
Se ejecute la función "crear".
Otro punto que no logro resolver es que al enviarle a mi XML la nueva información se pone errónea, ya que no tengo los parámetros.
| XML: | </technology>
</owner> |
Que fueron cerrados anteriormente.
Si alguno me puede ayudar, se lo voy agradecer mucho  |
|

Lun Jun 09, 2008 4:03 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
| No se parece mucho ese XML al que has enseñado en mensajes anteriores... |
|


Lun Jun 09, 2008 6:22 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
Repito: el módulo XML::Simple es para hacer cosas sencillas. Si queremos hacer cosas más elaboradas es mejor usar otros módulos.
En el caso que nos ocupa, yo siempre he tenido que pedir ayuda al módulo Data::Dumper, para ver la forma que tiene la estructura que XMLin() me devuelve. Y luego, usar esa misma estructura. Pero no siempre se consigue una salida perfecta con XMLout().
Por ejemplo:
| Perl: | #!/usr/bin/perl -s
use strict;
use warnings;
##
BEGIN {
eval "use XML::Simple";
if ( $@ ) {
warn "Error al cargar el modulo: XML::Simple\n"
. "Instalar Modulo:\n"
. "\t\tcpan XML::Simple\n\n";
exit();
}
}
our $crear;
our $name;
our $notes;
our $ip;
our $url;
## Ayuda del sistema
if ( ! $name and ! $notes and ! $ip and ! $url and ! $crear ) {
die "Uso: $0 [-name|-notes|-ip|-url]\n"
. "\t-name=pc Busqueda por nombre del host\n"
. "\t-notes=test Busqueda por nota\n"
. "\t-ip=1.1.1.1 Busqueda por direccion IP\n"
. "\t-url=https://10.0.0.1 Busqueda por url\n\n"
. "\t-crear Añade nuevos contenidos"
;
}
my $info = XMLin ('kk.xml', KeyAttr => 1, ForceArray => [ 'user' ]);
if ( ! $crear ) {
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $name and $pc-> {name } !~ /^ $name$/;
next if $notes and $pc-> {notes } !~ /^ $notes$/;
next if $ip and $pc-> {ip } !~ /^ $ip$/;
next if $url and $pc-> {url } !~ /^ $url$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t$user->{name} : $user->{password}\n";
}
}
}
else {
push @ {$info-> {technology }{pc }}, {
name => 'marcos3',
url => 'https://10.1.1.1',
ip => '10.3.3.3',
user => [{
name => 'admin',
password=> 4444,
date => 20080333,
}],
notes => 'culito',
};
#use Data::Dumper;
#print Dumper $info;
print XMLout ($info, RootName => 'owner', XMLDecl => 1 );
} | el resultado es
| XML: | <?xml version='1.0' standalone='yes'?>
<owner>
<technology name="test">
<pc name="marcos" ip="10.1.1.1" notes="test" url="https://10.1.1.1">
<user name="admin" date="20080101" password="123" />
<user name="root" date="20080101" password="123" />
</pc>
<pc name="marcos2" ip="10.2.2.2" notes="testno" url="https://10.2.2.2">
<user name="root" date="20080102" password="asd" />
</pc>
<pc name="marcos3" ip="10.3.3.3" notes="culito" url="https://10.1.1.1">
<user name="admin" date="20080333" password="4444" />
</pc>
</technology>
</owner> | mientras que si cambiamos la línea del XMLout() a
| Perl: | print XMLout ($info, RootName => 'owner', XMLDecl => 1, NoAttr => 1 ); | entonces la salida es:
| XML: | <?xml version='1.0' standalone='yes'?>
<owner>
<technology>
<name>test</name>
<pc>
<name>marcos</name>
<ip>10.1.1.1</ip>
<notes>test</notes>
<url>https://10.1.1.1</url>
<user>
<name>admin</name>
<date>20080101</date>
<password>123</password>
</user>
<user>
<name>root</name>
<date>20080101</date>
<password>123</password>
</user>
</pc>
<pc>
<name>marcos2</name>
<ip>10.2.2.2</ip>
<notes>testno</notes>
<url>https://10.2.2.2</url>
<user>
<name>root</name>
<date>20080102</date>
<password>asd</password>
</user>
</pc>
<pc>
<name>marcos3</name>
<ip>10.3.3.3</ip>
<notes>culito</notes>
<url>https://10.1.1.1</url>
<user>
<name>admin</name>
<date>20080333</date>
<password>4444</password>
</user>
</pc>
</technology>
</owner> | Los dos xml son perfectamente válidos, pero no están formateados según como nosotros queremos. Según la documentación de XML::Simple, con un poco de esfuerzo se puede conseguir definir cómo queremos exactamente esa salida, para que coincida con la que le dimos en la entrada. Pero la experiencia dice que, en algunas ocasiones, esa salida es casi imposible de encontrar con las opciones que se le pueden pasar a XMLout(). En esos casos, lo mejor es usar otro módulo XML distinto.
En los desarrollos en los que yo he utilizado XML::Simple, siempre me he preocupado de que tanto la salida como la entrada sean muy sencillos de generar. Para esto he seguido la siguiente estrategia: He creado primero la estructura de datos. Y luego la he mandado grabar con XMLout(). El resultado es un fichero xml. Luego, averiguar la combinación que debo usar en XMLin() para obtener la misma estructura de datos.
¿Qué otras alternativas hay? Hay centenares de módulos para XML. Yo probaría XML::Smart (llevo años buscando una buena escusa para usarlo), ya que es mucho más fácil de manejar que XML::Simple. |
|

Lun Jun 09, 2008 11:51 pm
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
Muchisimas gracias, como siempre aprendo mucho de este foro  |
|

Mar Jun 10, 2008 4:44 pm
|
 |
situ
Perlero Frecuente

|
Registrado: 09 Abr 2007
Mensajes: 132
|
|
|
|
|
Explorer,
Una consulta ahi pude ir advanzando con el script, ahora puedo encriptar y desencriptar la password .
Como puedo hacer para que la persona pueda ingresar mas de un usuario cuando esta creando un nuevo Host.
| Perl: |
#!/usr/bin/perl -s
use strict;
use warnings;
use POSIX qw(strftime );
my $hday= strftime ("%Y%m%d", localtime);
##Verificacion del modulo XML::Simple
BEGIN {
eval "use XML::Simple";
if ( $@ ) {
warn "Error al cargar el modulo: XML::Simple\n"
. "Instalar Modulo:\n"
. "\t\tcpan XML::Simple\n\n";
exit();
}
}
our $crear;
our $name;
our $notes;
our $ip;
our $url;
our $descrypt;
## Ayuda del sistema
if ( ! $name and ! $notes and ! $ip and ! $url and ! $crear and ! $descrypt) {
die "Uso: $0 [-name|-notes|-ip|-url|-crear|-descrypt]\n"
. "\t-name=pc Busqueda por nombre del host\n"
. "\t-notes=test Busqueda por nota\n"
. "\t-ip=1.1.1.1 Busqueda por direccion IP\n"
. "\t-url=https://10.0.0.1 Busqueda por url\n"
. "\t-crear Adjuntar nuevos contenidos\n"
. "\t-descrypt Desencriptar password\n"
;
}
my $info = XMLin ('kk.xml', KeyAttr => 1, ForceArray => [ 'user' ]);
if ( $name and $descrypt ) {
print "- Ingresar password de la key gpg\n";
system("gpg --no-options $name.pw.asc");
open my $FILE, '<', "$name.pw" or die $!;
my @lines = < $FILE>;
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $name and $pc-> {name } !~ /^ $name$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t $user->{name} : @lines\n";
system("rm -f $name.pw");
close $FILE;
exit ();
}
}
}
if ( ! $crear ) {
for my $pc ( @ {$info-> {technology }{pc }} ) {
next if $name and $pc-> {name } !~ /^ $name$/;
next if $notes and $pc-> {notes } !~ /^ $notes$/;
next if $ip and $pc-> {ip } !~ /^ $ip$/;
next if $url and $pc-> {url } !~ /^ $url$/;
print "$pc->{name} => $pc->{url} ($pc->{ip})\n";
for my $user ( @ {$pc-> {user }} ) {
print "\t $user->{name} : $user->{password}\n";
}
}
}
else {
print "- Ingresar nombre del Host: ";
my $hname= <STDIN>;
chop($hname);
print "- Ingresar url: ";
my $hurl= <STDIN>;
chop($hurl);
print "- Ingresar IP: ";
my $hip= <STDIN>;
chop($hip);
print "- Ingresar notas: ";
my $hnota= <STDIN>;
chop($hnota);
print "- Ingresar usuario: ";
my $huser= <STDIN>;
chop($huser);
## Creacion del archivo del password y la encriptacion
open (my $NHOST , "> $hname.pw");
print "- Ingresar password (el password no aparece): ";
system "stty -echo";
my $hpass= <STDIN>;
chop($hpass);
print $NHOST "$hpass";
close ($NHOST);
system "stty echo";
print "\n- Ingresar password de la key gpg\n";
system("gpg -ac --no-options $hname.pw");
system("rm -f $hname.pw");
##Termina el archivo del password y la encriptacion
push @ {$info-> {technology }{pc }}, {
name => $hname,
url => $hurl,
ip => $hip,
user => [{
name => $huser,
password=> "$hname.pw.asc",
date => $hday,
}],
notes => $hnota,
};
#use Data::Dumper;
#print Dumper $info;
#Escribo sobre el archivo xml la salida
open my $SV, q{>:encoding (iso- 8859- 1)}, 'kk.xml';
print $SV XMLout ($info, RootName => 'owner', XMLDecl => 1, NoAttr => 1 );
close ($SV)
}
|
Gracias. |
|

Powered by phpBB © 2001, 2005 phpBB Group
|