miércoles, 27 de septiembre de 2017

Buscando Archivos

A medida que hemos ido deambulando por nuestro sistema Linux, una cosa ha quedado extremadamente clara: Un sistema Linux típico ¡Tiene un montón de archivos! Esto provoca la pregunta, “¿Cómo podemos encontrar cosas?” Ya sabemos que el sistema de archivos de Linux está bien organizado según convenios que han pasado de generación en generación de los sistemas como-Unix, pero el gran número de archivos puede representar un problema desalentador.

En este capítulo, veremos dos herramientas que se utilizan para encontrar archivos en un sistema. Estas herramientas son:

  • locate – Encuentra archivos por el nombre
  • find – Busca archivos en una jerarquía de directorios
También veremos un comando que a menudo se usa con comandos de búsqueda de archivos para procesar la lista resultante de archivos:
  • xargs – Construye y ejecuta líneas de comando desde la entrada estándar
Además, presentaremos un par de comandos para ayudarnos en nuestras exploraciones:
  • touch – Cambia la hora de los archivos
  • stat – Muestra el estado de archivos y sistemas de archivos
locate – Buscar archivos de forma fácil

El programa locate realiza una búsqueda rápida en la base de datos de nombres de archivo, y luego muestra cada nombre que coincida con una cadena dada. Digamos, por ejemplo, que queremos buscar todos los programas con nombres que empiecen por “zip”. Como estamos buscando programas, podemos asumir que el nombre del directorio que contiene los programas terminará con “bin/”. Por lo tanto, podríamos intentar usar locate de esta forma para buscar nuestros archivos:

 [me@linuxbox ~]$ locate bin/zip

locate buscará en la base de datos de nombres de archivo y mostrará todo aquel que contenga la cadena “bin/zip”.

 /usr/bin/zip
 /usr/bin/zipcloak
 /usr/bin/zipgrep
 /usr/bin/zipinfo
 /usr/bin/zipnote
 /usr/bin/zipsplit

Si los requisitos de la búsqueda no son tan simples, locate puede combinarse con otras herramientas como grep para diseñar búsquedas más interesantes:

 [me@linuxbox ~]$ locate zip | grep bin
 /bin/bunzip2
 /bin/bzip2
 /bin/bzip2recover
 /bin/gunzip
 /bin/gzip
 /usr/bin/funzip
 /usr/bin/gpg-zip
 /usr/bin/preunzip
 /usr/bin/prezip
 /usr/bin/prezip-bin
 /usr/bin/unzip
 /usr/bin/unzipsfx
 /usr/bin/zip
 /usr/bin/zipcloak
 /usr/bin/zipgrep
 /usr/bin/zipinfo
 /usr/bin/zipnote
 /usr/bin/zipsplit

El programa locate ha estado por aquí desde hace muchos años, y hay varias variantes diferentes de uso común. Las dos más comunes que encontramos en las distribuciones de Linux modernas son slocate y mlocate, aunque a menudo son accesibles por un enlace simbólico llamado locate. Las diferentes versiones de locate tienen opciones superpuestas. Algunas versiones incluyen coincidencia de expresiones regulares (que veremos en un capítulo próximo) y soporte de comodines. Mira la man page de locate para determinar que versión de locate tienes instalada.


¿De donde sale la base de datos de locate?

Habrás notado que, en algunas distribuciones, locate falla al funcionar justo después de instalar el sistema, pero si lo intentas de nuevo al día siguiente, funciona bien. ¿Qué pasa? La base de datos de locate la crea otro programa llamado updatedb. Normalmente, se ejecuta periódicamente como un trabajo programado; o sea, una tarea realizada a intervalos regulares por demonio cron. La mayoría de los sistemas equipados con locate ejecutan updatedb una vez al día. Como la base de datos no se actualiza continuamente, notarás que los archivos muy recientes no aparecen cuando usas locate. Para solucionar esto, es posible ejecutar el programa updatedb manualmente entrando como superusuario y ejecutando updatedb en el prompt.


find – Encontrando archivos de forma difícil

Mientras que el programa locate puede encontrar un archivos basándose solamente en su nombre, el programa find busca en un directorio (y sus subdirectorios) archivos por una variedad de atributos. Vamos a pasar mucho tiempo con find porque tiene un montón de características interesantes que veremos una y otra vez cuando empecemos a ver conceptos de programación en capítulos posteriores.

En su uso más simple, find necesita uno o más nombres de directorios para buscar. Por ejemplo, para producir una lista de nuestro directorio home:

 [me@linuxbox ~]$ find ~

En la mayoría de las cuentas de usuario activas, producirá una gran lista. Como la lista se envía a la salida estándar, podemos desvíar la lista a otros programas. Usemos wcpara contar el número de archivos:

 [me@linuxbox ~]$ find ~ | wc -l
 47068



¡Guau, hemos estado ocupados! La belleza de find es que puede usarse para identificar archivos que cumplen criterios específicos. Lo hace a través de aplicaciones (un poco extrañas) de opciones, tests y acciones. Veremos los tests primero.

Tests

Digamos que queremos una lista de directorios de nuestra búsqueda. Para hacerlo, podríamos añadir el siguiente test:

 [me@linuxbox ~]$ find ~ -type d | wc -l
 1695

Añadiendo el test -type d limitamos la búsqueda a directorios. Inversamente, podríamos haber limitado la búsqueda a archivos normales con este test:

 [me@linuxbox ~]$ find ~ -type f | wc -l
 38737

Aquí tenemos los test de tipos de archivo más comunes soportados por find:

Tipos de archivo en find

b Archivo especial de bloques de dispositivo
c Archivo especial de carácter de dispositivo
d Directorio
f Archivo normal
l Enlace simbólico

También podemos buscar por tamaño de archivo y nombre de archivo añadiendo algunos tests adicionales. Busquemos todos los archivos normales que coinciden con el patrón con comodín “*.JPG” y que sean mayores de un megabyte:

 [me@linuxbox ~]$ find ~ -type f -name "*.JPG" -size +1M | wc -l
 840

En este ejemplo, añadimos el test -name seguido del patrón con comodín. Fíjate como lo hemos incluido entre comillas para prevenir la expansión de nombre por el shell. A continuación, añadimos el test -size seguido de la cadena “+1M”. El signo más al principio indica que estamos buscando archivos mayores que el número especificado. Un signo menos al principio cambiaría el significado de la cadena para que sea menor que el número especificado. No usar signo significa, “coincidencia del valor exacto”. La letra final “M” indica que la unidad de medida es megabytes. Los siguientes caracteres pueden usarse para especificar unidades:

Unidades de tamaño de find

b Bloques de 512 bytes. Es la opción por defecto si no especificamos ninguna unidad.
c Bytes
W Palabras de 2 bytes
k Kilobytes (unidades de 1024 bytes)
M Megabytes (unidades de 1048576 bytes)
G Gigabytes (unidades de 1073741824 bytes)

find soporta un gran número de tests diferentes. Abajo hay un paquete de los más comunes. Fíjate que en los casos en los que se requiere un argumento numérico, puede aplicarse la misma notación de “+” y “-” que vimos antes:

Tests de find

-cmin n 

Encuentra archivos o directorios cuyo contenido o atributos han sido modificado exactamente hace nminutos. Para especificar menos que n minutos, usa -n y para especificar más de n minutos usa +n

-cnewer archivo 
Encuentra archivos o directorios cuyo contenido o atributos han sido modificados más recientemente que el archivo archivo.

-ctime n 
Encuentra archivos o directorios cuyo contenido o atributos fueron modificados por última vez hace n*24 horas.

-empty 
Encuentra archivos y directorios vacíos

-group nombre 
Encuentra archivos o directorios que pertenecen a group. group podría expresarse tanto como un nombre de grupo o una ID numériResultado de expr1  Operador  expr2...ca de grupo.

-iname patrón 
Como el test -name pero sensible a mayúsculas

-inum n Encuentra archivos con el número de inodo n. Ésto es útil para encontrar todos los enlaces duros a un inodo particular.

-mmin n Encuentra archivos o directorios cuyo contenido fue modificados por última vez hace n minutos.

-mtime n 
Encuentra archivos o directorios cuyo contenido fue modificado por última vez hace n*24 horas.

-name Resultado de expr1  Operador  expr2...
patrón 
Encuentra archivos o directorios con la cadena patrón.

-newer archivo 
Encuentra archivos y directorios cuyo contenido fue modificado más recientemente que el archivoespecificado. Ésto es muy útil cuando escribimos scripts de hell que realizan copias de seguridad de archivos. Cada vez que haces una copia de seguridad, actualiza una archivo (como un log por ejemplo), y luego usa findpara determinar que archivos fueron cambiados desde la última actualización.

-nouser 
Encuentra archivos y directorios que no pertenecen a un usuario válido. Puede usarse para encontrar archivos pertenecientes a cuentas borradas o para detectar actividad de atacantes.

-nogroup 
Encuentra archivos y directorios que no pertenecen a un grupo válido.

-perm modo 
Encuentra archivos y directorios que tienen configuración de permisos en el modo especificado. modo podría expresarse tanto en octal como en notación simbólica.

-samefile nombre 
Igual que el test -inum. Encuentra archivos que comparten el mismo número de inodo que el archivo nombre.

-size n 
Encuentra archivos de tamaño n.

-type c 
Encuentra archivos de tipo c.

-user nombre 
Encuentra archivos o directorios que pertenezcan al usuario nombre. El usuario puede expresarse por un nombre de usuario o por un ID numérico de usuario.

Ésta no es una lista completa. La man page de find tiene todos los detalles.

Operadores

Incluso con todos los test que proporciona find, podríamos necesitar aún una mejor forma de describir las relaciones lógicas entre los test. Por ejemplo, ¿qué pasa si necesitamos determinar si todos los archivos y subdirectorios de un directorio tiene permisos seguros? Podríamos buscar todos los archivos con permisos que no son 0600 y los directorios con permisos que no son 0700. Afortunadamente, find cuenta con una forma de combinar test usando operadores lógicos para crear relaciones lógicas más complejas. Para expresar el test mencionado anteriormente, podríamos hacer ésto:

[me@linuxbox ~]$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

¡Uff! Seguro que te parece raro. ¿Qué es todo eso? Realmente, los operadores no son tan complicados una vez que los conoces. Aquí hay una lista:

Operadores lógicos de find

-and 

Mira si los tests en ambas caras del operador son verdad. Puede abreviarse a -a. Fíjate que cuando no hay operador presente, -andestá implícito por defecto.

-or Comprueba si un test que está en algún lado del operador es falso. Puede abreviarse a -o.

-not Comprueba si el test que sigue al operador es falso. Puede abreviarse con un signo de exclamación (!).

( ) Agrupa tests y operadores juntos para formar una expresión más grande. Se usa para controlar la precedencia de las evaluaciones lógicas. Por defecto, Para saber más
find evalua de izquierda a derecha. A menudo es necesario anular la precedencia por defecto para obtener el resultado deseado. Incluso si no es necesario, es útil a veces incluir los caracteres de agrupamiento para mejorar la legibilidad del comando. Fíjate que como los paréntesis tienen significado especial para el shell, deben ir entrecomillados cuando se usan en la línea de comandos para permitir que sean pasados como argumentos de find. Normalmente el carácter de la barra invertida se usa para ignorarlos.

Con esta lista de operadores a mano, deconstruyamos nuestro comando find. Cuando lo vemos desde el nivel superior, vemos que nuestros tests están ordenados como dos grupos separados por un operador -or:

( expresión 1 ) -or ( expresión 2 )

Esto tiene sentido, ya que estamos buscando archivos con una configuración de permisos determinados y directorios con una configuración distinta. Si estamos buscando tanto archivos como directorios, ¿por qué usamos -or en lugar de -and? Porque a medida que find busca a través de archivos y directorios, cada uno es evaluado para ver si coincide con los tests especificados. Queremos saber si es un archivo con malos permisos o un directorio con malos permisos. No puede ser los dos al mismo tiempo. Así que si expandimos las expresiones agrupadas, podemos verlo de esta forma:

( archivo con malos permisos ) -or ( directorio con malos permisos )

Nuestro próximo desafío es como buscar “malos permisos” ¿Cómo lo hacemos? En realidad no lo haremos. Lo que buscaremos será “permisos no buenos”, ya que sabemos que son “permisos buenos”. En el caso de archivos, definimos bueno como 0600 y para directorios, 0700. La expresión que buscará archivos con permisos “no buenos” es:

-type f -and -not -perms 0600

y para directorios:

-type d -and -not -perms 0700

Cómo apuntamos en la tabla de operadores anterior, el operador -and puede eliminarse con seguridad, ya que está implícito por defecto. Así que si ponemos todo junto, tenemos nuestro comando definitivo:

find ~ ( -type f -not -perms 0600 ) -or ( -type d -not -perms 0700 )

Sin embargo, como los paréntesis tienen un significado especial para el shell, tenemos que “escaparlos” para prevenir que el shell trate de interpretarlos. Precediendo cada uno con una barra invertida conseguimos el truco.

Hay otra característica de los operadores lógicos que es importante entender. Digamos que tenemos dos expresiones separadas por un operador lógico:

expr1 -operador expr2

En todos los casos, expr1 siempre se llevará a cabo; sin embargo, el operador determinará si expr2 se realizará. Aquí tenemos cómo funciona:

Lógica AND/OR de find

Resultado de expr1  Operador  expr2...
Verdadero          -and       se ejecuta siempre
Falso              -and       no se ejecuta
Verdadero          -or        no se ejecuta
Falso              -or        se ejecuta siempre

¿Por qué ocurre ésto? Para mejorar el rendimiento. Tomemos -and, por ejemplo. Sabemos que la expresión expr1 -and expr2 no puede ser verdadera si el resultado de expr1 es falso, luego es necesario que se ejecute expr2. Igualmente, si tenemos la expresión expr1 -or expr2 y el resultado de expr1 es verdadero, no es necesario que se ejecute la expr2 ya que ya sabemos que lafind ~ -print -and -type f -and -name '*.BAK'
 expresión expr1 -or expr2 es verdadera.

Ok, así que ayuda a que sea más rápido. ¿Por qué es importante? Es importante porque podemos contar con este comportamiento para controlar como se realizan las acciones, como veremos pronto.

Acciones predefinidas

¡Trabajemos! Tener una lista de resultados de nuestro comando find es útil, pero lo que realmente queremos hacer es actuar en los elementos de la lista. Afortunadamente, findpermite que las acciones se realicen basándose en los resultados de búsqueda. Hay una serie de acciones predefinidas y varias formas de aplicar acciones definidas por el usuario. Primero, veamos algunas acciones predefinidas:

Acciones predefinidas de find

-delete 

Borra el archivo buscado.

-ls 
Realiza el equivalente a ls -dils en el archivo buscado. La salida se envía a la salida estándar.

-print 
Envía la ruta completa del archivo buscado a la salida estándar. Es la acción por defecto si no se especifica ninguna otra acción.

-quit
Sale una vez que una búsqueda se ha realizado.

Como con los tests, hay muchas más acciones. Mira la man page de find para más detalles.

En nuestro primer ejemplo, hicimos esto:

 find ~

que produjo una lista de cada archivo y subdirectorio contenidos en nuestro directorio home. Produjo una lista porque la acción -print está implícita si no se especifica ninguna otra acción. Luego nuestro comando podría expresarse así también:

 find ~ -print

Podemos usar find para borrar archivos que cumplan ciertos criterios. Por ejemplo, para borrar archivos que tengan la extensión “.BAK” (que a menudo se usa para designar archivos de copia de seguridad), podríamos usar este comando:

 find ~ -type f -name '*.BAK' -delete

En este ejemplo, cada archivo en el directorio home del usuario (y sus subdirectorios) es buscado por si su nombre termina en .BAK. Cuando se encuentran, se borran.

Atención: No debería seguir sin decir que tengas extremo cuidado cuando uses la acción -delete. Siempre prueba el comando antes sustituyendo la acción -print por -delete para confirmar los resultados de búsqueda.

Antes de continuar, find ~ -type f -name '*.BAK' -print
echemos otro vistazo a cómo afectan a las acciones los operadores lógicos. Considera el siguiente comando:

 find ~ -type f -name '*.BAK' -print

Como hemos visto, este comando buscará cada archivo normal (-type f) cuyos nombres terminan en .BAK (-name '*.BAK') y enviará la ruta relativa de cada archivo coincidente a la salida estándar (-print). Sin embargo, la razón de que el comando funcione como lo hace viene determinada por la relación lógica entre cada test y su acción. Recuerda, hay, por defecto, una relación -and implícita entre cada test y cada acción. Podríamos expresar también el comando de esta forma para hacer la relación lógica más fácil de ver:

 find ~ -type f -and -name '*.BAK' -and -print

Con nuestro comando expresado completamente, veamos a como afectan los operadores lógicos a su ejecución:

Test/Acción   Se ejecuta sólo si...
-print        -type f y -name '*.BAK' son verdaderos
-name ‘*.BAK’ -type f es verdadero
-type f       Se ejecuta siempre, ya que es el primer 
              test/action en una relación -and.

Como la relación lógica entre los tests y las acciones determina cuales de ellos se ejecutan, podemos ver que el orden de los test y acciones es importante. Por ejemplo, si fuéramos a reordenar los test y las acciones para que la acción -print fuera la primera, el comando se comportaría de forma muy diferente:

 find ~ -print -and -type f -and -name '*.BAK'

Esta versión del comando imprimirá cada archivo (la acción -print siempre se evalúa como verdadera) y luego busca por tipo de a archivo y la extensión de archivo especificada.

Acciones definidas por el usuario

Además de las acciones predefinidas, podemos invocar también comandos arbitrarios. La forma tradicional de hacerlo es con la acción -exec. Esta acción funciona así:

-exec comando {} ;

donde comando es el nombre de un comando, {} es la representación simbólica de la ruta actual, y el punto y coma es un delimitador requerido indicando el final del comando. Aquí hay un ejemplo de usar -exec de forma que funcione como la acción -delete que vimos antes:

 -exec rm '{}' ';'

De nuevo, como las llaves y el punto y coma tiene significado especial para el shell, deben ir entrecomillados o “escapados”.

También es posible ejecutar una acción definida por el usuario interactivamente. Usando la acción -ok en lugar de -exec, el usuario es preguntado antes de la ejecución de cada comando especificado:

find ~ -type f -name 'foo*' -ok ls -l '{}' ';'
< ls ... /home/me/bin/foo > ? y
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/fooPara saber más
< ls ... /home/me/foo.txt > ? y
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

En este ejemplo, buscamos archivos con nombres que empiecen con la cadena “foo” y ejecutamos el comando ls -l cada vez que encontremos uno. Usar la acción -okpregunta al usuario antes de que se ejecute el comando ls.


Mejorando la eficiencia

Cuando usamos la acción -exec, arranca una nueva instancia del comando especificado cada vez que encuentra un archivo coincidente. Hay veces que podríamos preferir combinar todos los resultados de la búsqueda y arrancar una instancia única del comando. Por ejemplo, en lugar de ejecutar los comandos así:

ls -l archivo1
ls -l archivo2

podríamos preferir ejecutarlos así:

ls -l archivo1 archivo2

ésto hace que el comando se ejecute sólo una vez en lugar de muchas veces. Hay dos formas de hacer ésto. La forma tradicional, usando el comando externo xargs y la forma alternativa, usando una nueva característica del propio find. Hablaremos sobre la forma alternativa primero.

Cambiando el punto y coma del final por un signo más, activamos la capacidad de findde combinar los resultados de la búsqueda en una lista de argumentos para una ejecución única del comando deseado. Volviendo a nuestro ejemplo, ésto:

find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

ejecutará ls cada vez que encuentre un archivo coincidente. Cambiando el comando a:

find ~ -type f -name 'foo*' -exec ls -l '{}' +
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/fooPara saber más
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

tendremos los mismos resultados, pero el sistema sólo habrá ejecutado el comando lsuna vez.


xargs

El comando xargs realiza una función interesante. Acepta entradas de la entrada estándar y las convierte en una lista de argumentos para el comando especificado. Con nuestro ejemplo, podríamos usarlo así:

find ~ -type f -name 'foo*' -print | xargs ls -l
-rwxr-xr-x 1 me me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me me 0 2008-09-19 12:53 /home/me/foo.txt

Aquí vemos la salida del comando find entubada dentro de xargs lo que, sucesivamente, construye una lista de argumentos para el comando ls y luego lo ejecuta.


Nota: Mientras que el número de argumentos que pueden colocarse en una línea de comandos es bastante largo, no es ilimitado. Es posible crear comandos que son demasiado largos para que los acepte el shell. Cuando una línea de comandos excede la longitud máxima soportada por el sistema, xargs ejecuta el comando especificado con el máximo numero de argumentos posible y luego repite el proceso hasta quePara saber más
 la entrada estándar esté exPara saber máshausta. Para ver el tamaño máximo de la línea de comandos, ejecuta xargs con la opción --show limits.

Tratando con nombres de archivo simpáticos

Los sistemas como-Unix permiten espacios embebidos (¡e incluso nuevas líneas!) en los nombres de archivo. Esto causa problemas a programas como xargs que construyen listas de argumentos para otros programas. Un espacio embebido será tratado como un delimitador, y el comando resultante interpretará cada palabra separada por un espacio como un argumento separado. Para saber másPara remediar ésto, find y xarg permiten el uso opcional de un carácter nulo como separador de argumentos. Un carácter nulo se define en ASCII como el carácter representado por el número cero (en lugar de, por ejemplo, el carácter espacio, que se define en ASCII como el carácter representado por el número 32). El comando find cuenta con la acción -print0, que produce una salida separada por nulos, y el comando xargs tiene la opción --null, que acepta entradas separadas por nulos. Aquí tenemos un ejempPara saber máslo:

find ~ -iname '*.jpg' -print0 | xargs --null ls -l

Usando esta técnica, podemos asegurarnos que todos los archivos, incluso los que contienen espacios embebidos en sus nombres, son tratados correctamente.


Una vuelta al patio de juegos

Es hora de usar find de forma algo (al menos) práctica. Crearemos un patio de juegos y probaremos algo de lo que hemos aprendido.

Primero, creemos un patio de juegos con muchos subdirectorios y archivos:

 [me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
 [me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}

¡Maravíllense con el poder de la línea de comandos! Con estas dos líneas, hemos creado un directorio patio de juegos que contiene 100 subdirectorios cada uno conteniendo 26 archivos vacíos. ¡Inténtalo con la GUI!

El método que hemos empleado para realizar esta magia incluye un comando familiar (mkdir), una exótica expansión de shell (llaves) y un nuevo comando, touch. Combinando mkdir con la opción -p (que hace que mkdir cree los directorios padres de las rutas especificadas) con expansión con llaves, podemos crear 100 subdirectorios.

El comando touch se usa normalmente para establecer o actualizar, el acceso, cambio y fecha de modificación de los archivos. Sin embargo, si el argumento del nombre de archivos es el de un archivo que no existe, se crea un archivo vacío.

En nuestro patio de jPara saber másuegos, hemos creado 100 instancias de un archivo llamado file-A. Encontremoslas:

 [me@linuxbox ~]$ find playground -type f -name 'file-A'

Fijate que al contrario que ls, find no produce resultados ordenados. Su orden lo determina el dispositivo de almacenamiento. Podemos confirmar que realmente tenemos 100 instancias del archivo de esta forma:

 [me@linuxbox ~]$ find playground -type f -name 'file-A' | wc -l
 100


Para saber más
A continuación, veamos los archivos encontrados basándonos en su hora de modificación. Ésto será útil cuando creamos copias de seguridad o organizamos archivos en orden cronológico. Para hacerlo, primero crearemos un archivo de referencia contra el que compararemos la hora de modificación:

 [me@linuxbox ~]$ touch playground/timestamp

Ésto crea un archivo vacío llamado timestamp y establece su hora de modificación en la hora actual. Podemos verificarlo usando otro comando útil, stat, que es un tipo de versión vitaminada de ls. El comando stat revela todo lo que el sistema entiende sobre un archivo y sus atributos:

[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me)Para saber más
Access: 2008-10-08 15:15:39.000000000 -0400
Modify: 2008-10-08 15:15:39.000000000 -0400
Change: 2008-10-08 15:15:39.000000000 -0400

Si “tocamos” el archivo de nuevo y luego lo examinamos con stat, veremos que las horas del archivo se han actualizado:

[me@linuxbox ~]$ touch playground/timestamp
[me@linuxbox ~]$ stat playground/timestamp
File: `playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me)
Access: 2008-10-08 15:23:33.000000000 -0400
Modify: 2008-10-08 15:23:33.000000000 -0400
Change: 2008-10-08 15:23:33.000000000 -0400

A continuación, usemos find para actualizar algunos archivos de nuestro patio de juegos:

[me@linuxbox ~]$ find playground -type f -name 'file-B' -exec touch
'{}' ';'


Ésto actualiza todos los archivos del patio de juegos llamados file-B. Luego usaremosfind para identificar los archivos actualizados comparando todos los archivos con el archivo de referencia timestamp:

[me@linuxbox ~]$ find playground -type f -newer playground/timestamp


El resultado contiene las 100 instancias del archivo file-B. Como realizamos un touch en todos los archivos del patio de juegos llamados file-B después de actualizar timestamp, ahora son más “nuevos” que timestamp y por lo tanto pueden ser identificados con el test -newer.

Finalmente, volvamos al test de malos permisos que realizamos anteriormente y apliquémoslo a playground:

[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 \) -or \(-type d -not -perm 0700 \)

Este comando liPara saber mássta los 100 directorios y los 2600 archivos de playground (así comotimestamp y el propio playground, haciendo un total de 2702) porque ninguno de ellos entra en nuestra definición de “buenos permisos”. Con nuestro conocimiento de los operadores y las acciones, podemos añadir acciones a este comando para aplicar nuevos permisos a los archivos y directorios en nuestro patio de juegos:

[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \) -or \( -type d -not -perm 0700 -exec chmod 0700 '{}' ';' \)

En el día a día, podríamos encontrar más fácil manejarnos con dos comandos, uno para los directorios y otro para los archivos, en lugar de este gran comando complejo, pero es bueno saber que podemos hacerlo de esta forma. Lo importante aquí es entender cómo pueden usarse los operadores y las acciones juntos para realizaPara saber másr tareas útiles.


Opciones

Finalmente, tenemos las opciones. Las opciones se usan para controlar el alcance de una búsqueda con find. Podrían incluirse con otros test y acciones cuando se construyen expresiones con find. Aquí hay una lista de las más usadas:

Opciones find

-depth
Dirige find a procesar los archivos de un directorio antes del propio directorio. Esta opción se aplica automáticamente cuando se especifica la acción -delete.


-maxdepth levels
Establece el número máximo de niveles que find desciende en un árbol de directorios cuando realizamos tests y acciones.

-mindepth levels
Establece el número mínimo de niveles que find desciende en un árbol de directorios antes de aplicar tests y acciones.

-mount
Dirige find a no cruzar directorios que está montados en otros sistemas de archivos.

-noleaf
Dirige find a no optimizar su búsqueda asumiendo que está buscando en un sistema de archivos como-Unix. Ésto es necesario cuando buscamos en sistemas de archivos DOS/Windows y CD-ROMs

Resumiendo


Es fácil ver que locate es simple y que find es complicado. Ambos tienen sus usos. Tómate tiempo para explorar las muchas funciones de find. Puede, usándolo regularmente, mejora tu entendimiento de lPara saber más
as operaciones de los sistemas de archivo Linux.

Para saber más

  • Los programas locate, updatedb, find y xargs son parte del paquete GNU Project's findutils. El proyecto GNU ofrece un sitio web con una extensa documentación on-line, que es muy buena y deberías leerla si usas estos programas en entornos de alta seguridad:
    http://www.gnu.org/software/findutils

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.