• Publicidad

Archivo o directorio que no existe al usar ls -l

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

Archivo o directorio que no existe al usar ls -l

Notapor Camilein » 2012-12-02 17:01 @750

Hola nuevamente a todos.

Primero que todo mis disculpas, si el título del tema no es muy representativo... No se me ocurrió otro asunto qué ponerle.

Estoy generando un script, en el que yo indico el directorio, y que me busca los archivos con determinados permisos. Mi script funciona, me encuentra los archivos, pero el detalle es que además de imprimirme el resultado deseado, me imprime un montón de líneas que dicen por ejemplo:

ls: no se puede acceder a /home/camilo/.mozilla/firefox/Crash: No existe el archivo o el directorio

En un principio pensé que había olvidado poner para que se saltara los archivos especiales, pero sí lo había puesto. Así que no se me ocurre por qué puede pasar.

Sé que existe File::Find para hacer esto mismo, pero quiero hacerlo a mi manera =)

Adjunto va mi código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. # ls -l entrega :     permisos - N° de enlaces rígidos - propietario - grupo - tamaño(bytes) - ultima fecha de modificación
  3. # Ejemplo de ls -l -> -rwxrwxr-x        1                  camilo      camilo        0           dic  2 16:03                     buscarPeligrosos.pl
  4.  
  5. use strict;
  6.  
  7. my $directorio = @ARGV[0];
  8. if ( @ARGV <= 0 ) {
  9.     die "Uso: $0 <directorio>\n";
  10. }
  11.  
  12. chdir $directorio or die " No se puede abrir el directorio \n";
  13.  
  14. my @encontrados;                       #arreglo en el que se almacenan los archivos que coinciden
  15.  
  16. buscar($directorio);                   #llamado a la funcion
  17.  
  18. sub buscar {
  19.     my $directorio = shift;
  20.  
  21.     opendir DIR, $directorio or die "ERROR: Algo salio mal: $!\n";
  22.     my @archivos = readdir(DIR);
  23.     closedir DIR;
  24.  
  25.     for my $archivo (@archivos) {
  26.  
  27.         next if $archivo eq '.';
  28.         next if $archivo eq '..';
  29.  
  30.         my $file = "$directorio/$archivo";    #archivo con su ruta completa
  31.         print "$file\n";
  32.         if ( -f $file ) {
  33.             my $info = qx/ls -l $file/;
  34.             my @info_archivo = split( " ", $info );
  35.  
  36.             if (   @info_archivo[0] eq "-rwxrwxrwx"
  37.                 || @info_archivo[0] eq "-rwxrw-rw-"
  38.                 || @info_archivo[0] eq "-rw-rw-rw-" )    #realiza comparacion de permisos peligrosos
  39.             {
  40.                 my $linea = @info_archivo[0] . '  ' . @info_archivo[2] . '  ' . @info_archivo[8];
  41.                 push @encontrados, $linea;  # cada vez que se encuentra un archivo, este es agregado al arreglo con push
  42.                 next;
  43.             }
  44.         }
  45.         elsif ( -d $file )             #si $file es directorio llama a la funcion para entrar a ese directorio
  46.         {
  47.             buscar($file);
  48.         }
  49.     }
  50. }
  51.  
  52. if ( @encontrados <= 0 ) {
  53.     print "No hay archivos con permisos peligrosos\n";
  54. }
  55. else {
  56.     print "---Archivos Peligrosos---\n";
  57.     for my $archivo (@encontrados) {
  58.  
  59.         print "$archivo\n";
  60.     }
  61. }
  62.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Pues, muchas gracias de antemano por la ayuda.

Saludos
Camilein
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2012-09-26 14:07 @630

Publicidad

Re: Archivo o directorio que no existe al usar ls -l

Notapor explorer » 2012-12-02 17:37 @776

No estoy seguro, pero podría ser que el archivo a analizar hubiese desaparecido, desde el momento en que lo extraes desde la línea 22 hasta la línea 33.

Date cuenta que tienes hecho un proceso recursivo de recorrer los directorios, entonces puede pasar un tiempo hasta que accedes a esos archivos. Si son archivos temporales, pueden haber desaparecido. Y además, haces un 'ls' por cada archivo, que conlleva mucho tiempo y consumo de recursos de la máquina, por lo que tardará en recorrer los directorios.

Hay una forma más cómoda para realizar esto: existe la opción '-R' para el comando 'ls', que recorre todo el árbol de directorio de forma recursiva.

Una advertencia: no se debe escribir

@info_archivo[0]

sino

$info_archivo[0]

ya que solo estás accediendo a un solo elemento (consultar perldata).

Otra cosa: no necesitas hacer un 'ls' para obtener los detalles de cada archivo: con la función stat() ya lo tienes resuelto. En fin, todo esto ya te lo comenté antes.
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: Archivo o directorio que no existe al usar ls -l

Notapor Camilein » 2012-12-02 19:02 @834

Okas. Lo de usar $ en lugar del @ para acceder a un elemento, me di cuenta solo y lo arregle, lo del stat... soy culpable, lo había olvidado por completo, pero me entró la duda: si uso ls -R, y encuentro una coincidencia... ¿cómo sé en qué directorio está el archivo? La solución que se me había ocurrido es usar locate, porque al encontrar un archivo que coincida con los permiso indicados, debo además mostrar su ruta absoluta. ¡Ah! y al usar ls -R... ¿es posible revisar los archivos a medida que los va listando, y ver si es archivo o directorio?

Esup

El código que envié primero, funciona bien. Esos errores que tiraba eran de la distribución que estaba usando, probablemente referencias, que quedan de archivos que no existen, porque el mismo código lo probé en otra distribución recién instalada y funcionó de lo más bien sin tirar ni un solo error.
Camilein
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2012-09-26 14:07 @630

Re: Archivo o directorio que no existe al usar ls -l

Notapor explorer » 2012-12-03 12:32 @564

A ver... antes hay que resolver un tema de concepto...

¿Quieres hacer un programa en Perl, completamente en Perl, o usando comandos externos?

El problema que estás intentando resolver se puede resolver completamente en Perl. Es más, el propio Perl te va a realizar el programa por ti, como he indicado en otro hilo.

Otro caso es usar comandos externos, como 'ls', 'locate' (este no está instalado en todos los sistemas). Esto tiene el problema de que no te funcionará en todos los sistemas (por ejemplo, en Windows, ya que no disponen del comando 'ls').

Claro que se puede resolver con esos comandos externos... con mi propuesta de 'ls -lR' obtienes una visión recursiva de todo un árbol de directorios:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use File::Basename;
  7. use File::Listing qw(parse_dir);
  8.  
  9.  
  10. ## Directorio a analizar, pasado por argumento al programa
  11. my $directorio_base = shift // $ENV{HOME};
  12.  
  13. ## Comprobar que existe el directorio
  14. if (not -d $directorio_base) {
  15.     my($filename, $directories, $suffix) = fileparse($directorio_base);
  16.  
  17.     if (not -d $directories) {
  18.         die "ERROR: No encuentro el directorio $directorio_base: $!\n";
  19.     }
  20.  
  21.     $directorio_base = $directories;
  22. }
  23.  
  24. print "Analizando [$directorio_base]\n";
  25.  
  26. ## Listado recursivo de directorios
  27. $ENV{LANG} = "C"; # este módulo solo es capaz de interpretar fechas en formato original inglés
  28.  
  29. for (parse_dir(`ls -lR $directorio_base`)) {
  30.     my ($name, $type, $size, $mtime, $mode) = @$_;
  31.  
  32.     next if $type ne 'f';       # solo analizaremos archivos normales
  33.  
  34.     $mode = $mode & 0777;       # nos quedamos con los permisos más bajos
  35.  
  36.     if ($mode == 0777
  37.     or  $mode == 0766
  38.     or  $mode == 0666
  39.     ) {
  40.         printf "\t%04o %s\n", $mode, $name;
  41.     }
  42. }
  43. __END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
explorer@casa:~/Documentos/Desarrollo> ./kk.pl ~/Documentos/Desarrollo/test
Analizando [/media/500_1/home/explorer/Documentos/Desarrollo/test]
        0666 /media/500_1/home/explorer/Documentos/Desarrollo/test/test.pl~
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Pero entonces... ¿por qué no seguimos con el mismo razonamiento, y utilizamos comandos externos que ahorren aún más trabajo?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my $directorio_base = shift // $ENV{HOME};
  3.  
  4. print "Listado de archivos peligrosos:\n";
  5. my @archivos = qx(find $directorio_base -type f -perm 0777 -o -perm 0766 -o -perm 0666);
  6.  
  7. print "\t$_" for @archivos;
  8.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El verdadero reto es resolver el problema completamente en Perl :)
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


Volver a Básico

¿Quién está conectado?

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

cron