• Publicidad

Impresión recursiva de directorios

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

Re: Impresión recursiva de directorios

Notapor chanozg » 2012-02-05 12:01 @542

Pero a partir del mio ¿qué arreglo debería hacerle para completar el tema de la sangrías?

Y lo de los permisos, ¿a qué últimos mensajes se refiere?

Disculpa, pero es que mirando el de mi compañero me he liado bastante más.
chanozg
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2012-02-04 15:02 @668

Publicidad

Re: Impresión recursiva de directorios

Notapor explorer » 2012-02-05 17:37 @775

Creo que el fallo viene porque sin_x y sin_r son en sí mismos subdirectorios, pero no tienen ningún archivo dentro, junto con el hecho de que haces el print "\n"; en la llamada recursiva siguiente, y no en el print() del subdirectorio...

Quizás sea mejor redefinir la forma de resolver esto... Es decir, pensar qué debe ocurrir dentro de la subrutina para que pinte todos los contenidos, siguiendo un orden. Lo que me preocupa es que el ejemplo de salida que has mostrado tiene un excepción grave (la primera columna), que hace difícil encontrar una solución cómoda. En el hilo anterior, la salida del directorio era solo con sangrado de espacios en blanco, nada de '|', '-' ni '\', por lo que era más fácil de solventar.

Lo de los últimos mensajes del hilo enlazado antes, es que explica porqué no salen los avisos de error en los subdirectorios sin_x y sin_r: es porque sus permisos sí están puestos, al haber sido descomprimidos desde un archivo zip. Empieza por leer el hilo por el final (página 3), y encontrarás la forma de arreglarlo para que salgan los mismos mensajes.
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: Impresión recursiva de directorios

Notapor explorer » 2012-02-05 18:25 @809

Encontré una solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #
  3. use autodie;
  4.  
  5. mostrar_directorio('..');                          # Ejemplo
  6.  
  7. sub mostrar_directorio {
  8.     my $dir = shift;
  9.     print "$dir (Directorio de partida)\n";        # La función solo pinta la cabecera
  10.     mostrar_directorio_recursivo($dir, '');        # e inicializa el proceso recursivo
  11. }
  12.  
  13. sub mostrar_directorio_recursivo {
  14.     my($dir,$sangrado) = @_;
  15.  
  16.     my $DIR;                                       # obtenemos todo el contenido del $dir
  17.     opendir($DIR, $dir);
  18.     my @contenido = grep { !/^\.{1,2}$/ } readdir($DIR);
  19.     closedir $DIR;
  20.  
  21.     my $del = '|';                                 # delimitador por defecto para todos los contenidos
  22.  
  23.     for my $entrada (@contenido) {                 # recorremos todos los contenidos
  24.         my $ruta = "$dir/$entrada";
  25.            
  26.         if ($entrada eq $contenido[-1]) {          # cambiamos el delimitador, si es el último contenido
  27.             $del = '\\';
  28.         }
  29.  
  30.         if (-d $ruta) {                            # es un directorio
  31.  
  32.             print "$sangrado$del- $entrada(Directorio)";
  33.            
  34.             if (!-r $ruta) {                       # casos especiales
  35.                 print " >>>> ERROR: A <$ruta> le falta el permiso de lectura.\n";
  36.                 next;
  37.             }
  38.             if (!-x $ruta) {
  39.                 print " >>>> ERROR: A <$ruta> le falta el permiso de busqueda.\n";
  40.                 next;
  41.             }
  42.  
  43.             print "\n";
  44.  
  45.             my $nuevo_sangrado = $sangrado;        # cálculo del sangrado
  46.             if ($del eq '|') {
  47.                 $nuevo_sangrado .= '| ';                # es un sangrado dentro de un dir. dentro de otro
  48.             }
  49.             else {
  50.                 $nuevo_sangrado .= '  ';                # es un sangrado del último dir.
  51.             }
  52.                                                    # Llamada recursiva
  53.             mostrar_directorio_recursivo($ruta, $nuevo_sangrado);
  54.         }
  55.         else {                                     # es un archivo normal
  56.             print "$sangrado$del- $entrada\n";
  57.         }
  58.     }
  59. }
  60.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Ahora sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
.. (Directorio de partida)
|- etc(Directorio)
| |- group2
| |- passwd
| |- group
| \- passwd2
|- script(Directorio)
| |- code_29559_1.pl
| |- enunciado_rubrica_v1.pdf
| |- historico.txt
| |- pruebas.bash
| |- config3.txt
| |- historico2.txt
| |- minishell.pl~
| |- pruebas2.txt
| |- salida.pdf
| |- config2.txt
| |- enunciado_rubrica_v1.odt
| |- pruebas3.txt
| |- salida.txt
| |- minishell.pl
| |- salida.odt
| |- pruebas.txt
| |- entradas.txt
| \- config.txt
|- home(Directorio)
| |- sin_x(Directorio) >>>> ERROR: A <../home/sin_x> le falta el permiso de busqueda.
| \- sin_r(Directorio) >>>> ERROR: A <../home/sin_r> le falta el permiso de lectura.
\- home2(Directorio)
  |- alum1(Directorio)
  | |- f1
  | |- f2
  | \- f3
  |- alum3(Directorio)
  \- alum2(Directorio)
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Pero no sé si funcionará en todos los casos... no he hecho muchas pruebas.
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: Impresión recursiva de directorios

Notapor chanozg » 2012-02-05 18:45 @823

¡Parece que está perfecto!

Lo de los permisos que me decías, me leí el hilo y lo que entendí es que ese error aparecerá o no dependiendo de cómo se haya realizado la descarga del archivo zip, es decir, que no depende de mi script, ¿verdad?

Es decir, que doy por hecho que a mi profesor sí que le debería salir esos ERRORES.
chanozg
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2012-02-04 15:02 @668

Re: Impresión recursiva de directorios

Notapor explorer » 2012-02-05 18:56 @831

La saldrán esos errores porque los subdirectorios tienen los permisos puestos para que salgan esos errores.

Entonces, la respuesta es sí: tu programa funciona.

Ahora bien, si quieres quedarte tranquilo, entonces en ese hilo, al final, vienen las instrucciones para darles esos permisos a los subdir. y que salgan luego los mensajes de error. Pero ya digo, esto es opcional, porque depende de la estructura de archivos que tengas en ese momento.
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: Impresión recursiva de directorios

Notapor chanozg » 2012-02-05 19:04 @836

He encontrado este fallo

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
4 : mostrar_directorio nada
nada (Directorio de partida)
readdir() attempted on invalid dirhandle $DIR at minishell.pl line 180, <> line 4.
closedir() attempted on invalid dirhandle $DIR at minishell.pl line 181, <> line 4.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


cuando lo que debería salirme es

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
4 : mostrar_directorio nada
>>>> ERROR: No existe <nada>
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
chanozg
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2012-02-04 15:02 @668

Re: Impresión recursiva de directorios

Notapor explorer » 2012-02-05 19:10 @840

No sabía que había que hacer eso.

De todas maneras, la solución es muy sencilla, ¿no?
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: Impresión recursiva de directorios

Notapor chanozg » 2012-02-05 19:20 @847

Añadi lo siguiente pero sigue saliendome diferente

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  
  2. mostrar_directorio('..');    #
  3.  
  4. sub mostrar_directorio {
  5.     my $dir = shift;
  6.     print "$dir (Directorio de partida)\n";
  7.     mostrar_directorio_recursivo($dir, '');
  8. }
  9.  
  10. sub mostrar_directorio_recursivo {
  11.     my($dir,$sangrado) = @_;
  12.  
  13.     my $DIR;
  14.     opendir($DIR, $dir);
  15.     my @contenido = grep { !/^\.{1,2}$/ } readdir($DIR);
  16.     closedir $DIR;
  17.  
  18.     my $del = '|';
  19.  
  20.     if ( !@contenido ) {
  21.         $del = '\\'; # Caso de subdir vacío
  22.     }
  23.  
  24.     for my $entrada (@contenido) {
  25.         my $ruta = "$dir/$entrada";
  26.            
  27.         if ($entrada eq $contenido[-1]) {
  28.             $del = '\\';
  29.         }
  30.  
  31.         if (-d $ruta) {               # Directorio
  32.             print "$sangrado$del- $entrada(Directorio)";
  33.  
  34.             if (!-e $ruta) {
  35.                 print(">>>> ERROR: No existe <$ruta>\n");
  36.                 next;
  37.             }
  38.            
  39.             if (!-r $ruta) { #Lectura
  40.                 print " >>>> ERROR: A <$ruta> le falta el permiso de lectura.\n";
  41.                 next;
  42.             }
  43.  
  44.             if (!-w $ruta) { # Modificacion
  45.                 print ">>>> ERROR: A <$ruta> le falta el permiso de modificacion.\n";
  46.                 next;
  47.             }
  48.  
  49.             if (!-x $ruta) { #Busqueda
  50.                 print " >>>> ERROR: A <$ruta> le falta el permiso de busqueda.\n";
  51.                 next;
  52.  
  53.             }
  54.  
  55.             print "\n";
  56.  
  57.             my $nuevo_sangrado = $sangrado;
  58.             if ($del eq '|') {
  59.                 $nuevo_sangrado .= '| ';
  60.             }
  61.             else {
  62.                 $nuevo_sangrado .= '  ';
  63.             }
  64.             mostrar_directorio_recursivo($ruta, $nuevo_sangrado);
  65.         }
  66.         else {
  67.             print "$sangrado$del- $entrada\n";          # Archivo normal
  68.         }
  69.     }
  70. }
  71.  
  72.  
  73.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
chanozg
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2012-02-04 15:02 @668

Re: Impresión recursiva de directorios

Notapor explorer » 2012-02-05 20:18 @887

No tiene sentido preguntar por la no-existencia de un archivo/directorio, porque sabemos que sí existe (fue leído unas líneas antes por readdir).

Entonces, para contemplar el caso especial de que el usuario introduzca el nombre de un directorio que no exista (o de un archivo normal), lo que hay que hacer es poner esas comprobaciones dentro de mostrar_directorio(). Las líneas 32 a 37 tienes que subirlas allí.
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: Impresión recursiva de directorios

Notapor chanozg » 2012-02-05 20:46 @907

Creo que este es el definitivo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. mostrar_directorio('..');    #  Ejemplo
  2.  
  3. sub mostrar_directorio {
  4.     my $dir = shift;
  5.  
  6.         if (!-e $dir) {  # Comprobar si existe
  7.                 print(">>>> ERROR: No existe <$dir>\n");
  8.                 return;
  9.         }
  10.  
  11.     print "$dir (Directorio de partida)\n"; # Escribir cabecera
  12.     mostrar_directorio_recursivo($dir, ''); # Inicializa el proceso recursivo
  13. }
  14.  
  15. sub mostrar_directorio_recursivo {
  16.     my($dir,$sangrado) = @_;
  17.  
  18.     my $DIR; # Obtener contenido del $dir
  19.     opendir($DIR, $dir);
  20.     my @contenido = grep { !/^\.{1,2}$/ } readdir($DIR);
  21.     closedir $DIR;
  22.  
  23.     my $del = '|';  # Delimitador por defecto para todos los contenidos
  24.  
  25.     for my $entrada (@contenido) { # Recorrer todos los contenidos
  26.         my $ruta = "$dir/$entrada";
  27.            
  28.         if ($entrada eq $contenido[-1]) { # Cambiamos el delimitador
  29.             $del = '\\';
  30.         }
  31.  
  32.         if (-d $ruta) {               # Directorio
  33.             print "$sangrado$del- $entrada(Directorio)";
  34.  
  35.             if (!-r $ruta) { #Lectura
  36.                 print " >>>> ERROR: A <$ruta> le falta el permiso de lectura.\n";
  37.                 next;
  38.             }
  39.  
  40.             if (!-w $ruta) { # Modificación
  41.                 print ">>>> ERROR: A <$ruta> le falta el permiso de modificación.\n";
  42.                 next;
  43.             }
  44.  
  45.             if (!-x $ruta) { #Búsqueda
  46.                 print " >>>> ERROR: A <$ruta> le falta el permiso de búsqueda.\n";
  47.                 next;
  48.             }
  49.  
  50.             print "\n";
  51.  
  52.             my $nuevo_sangrado = $sangrado; # Cálculo de sangrado
  53.             if ($del eq '|') {
  54.                 $nuevo_sangrado .= '| '; # Sangrado dentro de un dir. dentro de otro
  55.             }
  56.             else {
  57.                 $nuevo_sangrado .= '  '; # Sangrado del último dir.
  58.             }
  59.  
  60.             mostrar_directorio_recursivo($ruta, $nuevo_sangrado); # Llamada recursiva
  61.         }
  62.         else {
  63.             print "$sangrado$del- $entrada\n";          # Archivo normal
  64.         }
  65.     }
  66. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4



Lo que me falta por saber es si el ERROR de búsqueda está bien donde lo puse.

¡Gracias!
chanozg
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2012-02-04 15:02 @668

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 11 invitados