• Publicidad

Ejercicio con hashes y archivos

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Ejercicio con hashes y archivos

Notapor olgamc » 2013-09-04 05:30 @271

Hola, estoy empezando con Perl, la verdad no sé mucho, y estoy intentando hacer un ejercicio que me han mandado y creo que es demasiado para mi, espero que puedan echarme una mano y orientarme en lo que tengo. Gracias.

También me dicen que no se permite usar la orden system() o equivalente dentro del programa como podría hacerse.

Debo hacer lo siguiente:
Leer etc/group y pasarlo a una estructura llamada VGrupos.

Luego nos pedirán de forma cíclica un nombre de grupo y un GID, se llamará a una función que añada dicho grupo a la estructura VGrupos; esta función recibirá por valor el GID y nombre de grupo por referencia VGrupos.

Comprobaremos que no existe grupo con otra función, ésta usará la estructura HASH (creada antes indicando dicha situación y su GID), si no existe continúa el alta.

Cuando se pulse el nombre del grupo vacío, entendemos que no queremos seguir introduciendo grupos y pasamos nuestra estructura al fichero etc/group.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. opendir(DIR,"etc");
  2. open(USUARIOS,"etc/passwd") or die "No se puede abrir el fichero. $!";
  3. #Preparamos un hash que tenga para cada usuario su GID
  4. while($var=<USUARIOS>)
  5. {
  6.    @vector=split /:/,$var;
  7.    $usuarios{$vector[0]}=$vector[3];
  8. }
  9.  
  10. close(USUARIOS);
  11.  
  12. open(VGRUPOS,"etc/group") or die "No se puede abrir el fichero. $!";
  13. #Preparamos un hash que tenga para cada GID el nombre del grupo
  14. while($var2=<VGRUPOS>)
  15. {
  16.    @vector_2=split /:/,$var2;
  17.    $vgrupos{$vector_2[2]}=$vector_2[0];
  18. }
  19. close(VGRUPOS);
  20. closedir(DIR);
  21. #Realización de una copia de seguridad de los directorios de casa
  22. #de todos los usuraios para el posterior traslado de los mismos
  23. mkdir("Auxiliar",0777) or die "no se puede crear el directorio Auxiliar";
  24. system("mv home/* Auxiliar");
  25. opendir(HOME,"home");
  26. #Ahora se crean los directorios respectivos para cada grupo
  27. $base="home/";
  28. foreach $directorio(values %vgrupos)
  29. {
  30.    $nombre=$base.$directorio;
  31.    mkdir($nombre,0777) or die "No se puede crear el directorio $nombre";
  32. }
  33. closedir(HOME);
  34. while(($usuario,$gid)=each %usuarios)
  35. {
  36.    $grupo=$vgrupos{$gid};
  37.    $dir=$base.$grupo."/";
  38.    $aux="Auxiliar/".$usuario;
  39.    system("mv $aux $dir");
  40. }
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
olgamc
Perlero nuevo
Perlero nuevo
 
Mensajes: 19
Registrado: 2013-09-04 04:27 @227

Publicidad

Re: Ejercicio con hashes y archivos

Notapor explorer » 2013-09-04 13:06 @587

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

El opendir() de la línea 1, creo que no sirve para nada.

Como no puedes usar system(), debes sustituir las operaciones mv con otras alternativas, como por ejemplo el método move() del módulo File::Copy, que viene incluido con Perl.

La descripción del ejercicio habla de crear funciones, pero no tienes ninguna sub {} definida.

El código está haciendo unas copias de directorios, que no es lo que te están pidiendo, sino algo más sencillo: leer y modificar el archivo etc/group.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Ejercicio con hashes y archivos

Notapor olgamc » 2013-09-05 03:30 @187

Gracias por tu respuesta, veo que es un completo desastre lo que tengo.

¿Estaría haciendo correctamente leer el fichero y pasarlo a la estructura o tampoco hago bien eso? Me pongo a trabajar en ello. Gracias nuevamente, por tu ayuda y tus indicaciones.
olgamc
Perlero nuevo
Perlero nuevo
 
Mensajes: 19
Registrado: 2013-09-04 04:27 @227

Re: Ejercicio con hashes y archivos

Notapor explorer » 2013-09-05 03:56 @205

Una forma de saber si hemos construido bien la estructura, es volcarla en pantalla o disco con la ayuda de Data::Dumper:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. print Dumper \%vgrupos;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Ejercicio con hashes y archivos

Notapor olgamc » 2013-09-05 05:12 @258

Gracias, no conocía Data::Dumper tengo que ver cómo se usa.

Sigo intentando avanzar, estoy con esto, ¿qué te parece... va bien?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(vGRUPOS,"etc/group") or die "No se puede abrir etc/group $!";
  2. $indice=0;
  3. while ($linea_grupos=<vGRUPOS>){
  4.                
  5.                 $lista_grupos[$indice]=$linea_grupos;
  6.                 $indice++;
  7. }
  8. chomp(@lista_grupos);
  9. foreach $linea (@lista_grupos)
  10. {
  11.         @grupo=split /:/,$linea;
  12.         $hash_grupo{$grupo[2]}=$grupo[0];  
  13. }
  14. close(vGRUPOS) or die "No se puede cerrar etc/group $!";
  15. open(PASW,"etc/passwd") or die "No se puede abrir etc/passwd $!";
  16. open(PASW2,">etc/passwd2") or die "No se puede abrir etc/passwd2 $!";
  17. $i=0;
  18. while ($linea_usuarios=<PASW>)
  19. {
  20.         $lista_usuarios[$i]=$linea_usuarios;
  21.         $i++;
  22. }
  23. chomp(@lista_usuarios);
  24. foreach $lin (@lista_usuarios)
  25. {
  26.         @usuario=split /:/,$lin;  #para cada valor de la lista
  27.         foreach $us (keys %hash_grupo){
  28.               if($us eq $usuario[3]){           #si los GID coinciden
  29.                 $dir_ent_nuevo="home/".$hash_grupo{$us}."/".$usuario[0];  
  30.                 print PASW2 "$usuario[0]:$usuario[1]:$usuario[2]:$usuario[3]:$usuario[4]:$dir_ent_nuevo:$usuario[6]";
  31.              }
  32.         }
  33. }
  34. rename("etc/passwd","etc/passwd2");  
  35. close(PASW);
  36. close(PASW2);
  37.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
olgamc
Perlero nuevo
Perlero nuevo
 
Mensajes: 19
Registrado: 2013-09-04 04:27 @227

Re: Ejercicio con hashes y archivos

Notapor explorer » 2013-09-05 05:50 @285

En la descripción del ejercicio no se habla para nada de acceder al archivo de usuarios, solo al de grupos...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Ejercicio con hashes y archivos

Notapor olgamc » 2013-09-05 06:01 @292

Lo hacía por que creía que los usuarios pertenecían a los grupos y era necesario. Veo que estaba en un error. :|
olgamc
Perlero nuevo
Perlero nuevo
 
Mensajes: 19
Registrado: 2013-09-04 04:27 @227

Re: Ejercicio con hashes y archivos

Notapor explorer » 2013-09-05 06:48 @325

"Leer etc/group y pasarlo a una estructura llamada VGrupos."

Esto se hace abriendo el archivo y pasando la información a un hash, indexado por el nombre del grupo, para luego facilitar la búsqueda de información de un grupo basada en su nombre (saber si ya existe, sobre todo).


"Luego nos pedirán de forma cíclica un nombre de grupo y un GID,"

Otro bucle donde tenemos que leer dos entradas del usuario, por la entrada estándar.


"se llamará a una función que añada dicho grupo a la estructura VGrupos; esta función recibirá por valor el GID y nombre de grupo por referencia VGrupos."

Hay que definir una función que reciba esos dos argumentos, y de esa manera: como valor y como referencia.


"Comprobaremos que no existe grupo con otra función, ésta usará la estructura HASH (creada antes indicando dicha situación y su GID), si no existe continúa el alta."

Hay que definir otra función, que recibirá los mismos argumentos. Devolverá un valor de verdad según el nombre del grupo exista o no en el hash %vgrupos.


"Cuando se pulse el nombre del grupo vacío, entendemos que no queremos seguir introduciendo grupos y pasamos nuestra estructura al fichero etc/group."

Si después de leer el nombre del grupo que el usuario quiere añadir a vgrupos, es una cadena vacía, pues salimos del bucle, y pasamos a la parte de grabación de %vgrupos a disco.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Ejercicio con hashes y archivos

Notapor olgamc » 2013-09-05 14:32 @647

Pues sigo trabajando en el ejercicio después de tus palabras, esto es lo que he hecho ahora, espero que esté mejor, tengo alguna duda si el foreach está bien o hay algún fallo de sintaxis:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(VGRUPOS,"etc/group") or die "No se puede abrir el fichero. $!";
  2. #Preparamos un hash que tenga para cada GID el nombre del grupo
  3. while($var=<VGRUPOS>)
  4. {
  5.    @vector_=split /:/,$var;
  6.    $vgrupos{$vector_[2]}=$vector_[0];
  7. }
  8. close(VGRUPOS);
  9. open(NEWGRUPOS,"etc/group2") or die "No se puede abrir el fichero. $!";
  10.  
  11. do
  12. {
  13.         print "Introduzca un nombre de grupo : ";
  14.         $nombre=<STDIN>;
  15.         print "Introduzca un GID : ";
  16.         $gid=<STDIN>;
  17.        
  18.         comprobar_gid($vgrupos,$nombre,$gid);
  19. }
  20. while $nombre!=<>;
  21.  
  22. sub comprobar_gid
  23. {
  24.         foreach $gr (keys $_[0]){
  25.                 if($gr eq $_[1]){               #si los GID coinciden
  26.                 <NEWGRUPOS> = $_[1].":".$_[2]."\n";
  27.                 print NEWGRUPOS "$_[1]:$_[2]";
  28.                 }
  29.         }
  30. }
  31. close(NEWGRUPOS);
  32.  
  33.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
olgamc
Perlero nuevo
Perlero nuevo
 
Mensajes: 19
Registrado: 2013-09-04 04:27 @227

Re: Ejercicio con hashes y archivos

Notapor explorer » 2013-09-05 19:49 @867

Hay que hacer varios cambios.

De forma correcta, creas %vgrupos, pero luego no haces uso de ella.

La variable $vgrupos que usas en la línea 18 no tiene nada que ver con el hash %vgrupos. Te faltaría en todo caso una línea

$vgrupos = \%vgrupos;

y así sería correcta la línea 18 (pasar la estructura %vgrupos como una referencia).

Has escrito una función que se llama comprobar, pero el ejercicio te dice que debes crear dos. La primera será "insertar", que se encarga de actualizar la estructura %vgrupos, pero lo primero que hace dentro de ella es llamar a "comprobar" para ver si ese grupo ya está metido o no.

En la subrutina comprobar_gid haces un bucle, cuando en realidad no debería haber ninguno. Bastaría con un
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ($_[0]->{$nombre_nuevo_grupo}) {
  2.     # aquí llegamos cuando sí hay un grupo que se llama igual que el $nombre_nuevo_grupo
  3.     return 1;
  4. }
  5. else {
  6.     return 0;
  7. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Bueno, el devolver '0' o '1' depende del sentido que le des a la expresión "comprobar".

Dentro de "comprobar" has intentado poner las líneas de "insertar". La línea 26 es un error de sintaxis. Para imprimir a un archivo se usa print, como lo tienes en la 27. A propósito, en la línea 9 estás abriendo el archivo en modo lectura, no escritura.

En la descripción del problema no habla nada de comparar los GID, ¿verdad? Solo el nombre de los grupos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Google [Bot] y 2 invitados