localizar vs encontrar: uso, pros y contras entre sí

Respuestas:

166

locate(1)solo tiene una gran ventaja sobre find(1): la velocidad.

find(1)Sin embargo, tiene muchas ventajas sobre locate(1):

  • find(1)es primordial, volviendo a la primera versión de AT&T Unix . Incluso lo encontrará en Linux incrustado reducido a través de Busybox . Es todo menos universal.

    locate(1)es mucho más joven que find(1). El primer antepasado de locate(1) no apareció hasta 1983 , y no estuvo ampliamente disponible como " locate" hasta 1994, cuando fue adoptado en GNU findutils y en 4.4BSD .

  • locate(1)tampoco es estándar , por lo que no está instalado por defecto en todas partes. Algunos sistemas operativos tipo POSIX ni siquiera lo ofrecen como una opción, y donde está disponible, la implementación puede carecer de las características que desea porque no hay un estándar independiente que especifique el conjunto mínimo de características que debe estar disponible.

    Hay un facto estándar, siendo BSDlocate(1) , pero eso es sólo porque los otros dos sabores principales de locateponer en práctica todas sus opciones: -0, -c, -d, -i, -l, -m, -s, y -S. mlocateimplementa 6 opciones adicionales no en BSD locate: -b, -e, -P, -q, --regexy -w. GNUlocate implementa los seis más otros cuatro : -A, -D, -E, y -p. (Estoy ignorando alias y diferencias menores como -?vs -hvs. --help)

    Los BSD y Mac OS X incluyen BSD locate.

    La mayoría de Linuxes envían GNU locate, pero Red Hat Linuxes y Arch se envían en su mlocatelugar. Debian tampoco se instala en su instalación base, pero ofrece ambas versiones en sus repositorios de paquetes predeterminados; si ambos se instalan a la vez, " locate" se ejecuta mlocate.

    Oracle ha estado enviando mlocateen Solaris desde 11.2 , lanzado en diciembre de 2014. Antes de eso, locateno estaba instalado de manera predeterminada en Solaris. (Presumiblemente, esto se hizo para reducir la incompatibilidad de comandos de Solaris con Oracle Linux , que se basa en Red Hat Enterprise Linux , que también usa mlocate).

    IBM AIX todavía no envía ninguna versión de locate, al menos a partir de AIX 7.2 , a menos que instale GNU findutilsdesde AIX Toolbox para aplicaciones Linux .

    HP-UX también parece faltar locateen el sistema base.

    Los Unixes "reales" más antiguos generalmente no incluían una implementación de locate.

  • find(1)tiene una potente sintaxis de expresión, con muchas funciones, operadores booleanos , etc.

  • find(1)puede seleccionar archivos por más que solo nombre. Se puede seleccionar por:

    • años
    • Talla
    • propietario
    • Tipo de archivo
    • marca de tiempo
    • permisos
    • profundidad dentro del subárbol ...
  • Al buscar archivos por nombre, puede buscar utilizando la sintaxis global de archivos en todas las versiones de find(1)GNU o BSD, utilizando expresiones regulares .

    Las versiones actuales de locate(1)aceptan patrones globales como lo findhace, pero BSD locateno hace expresiones regulares en absoluto. Si eres como yo y tienes que usar una variedad de tipos de máquinas, prefieres grepfiltrar que desarrollar una dependencia de -ro --regex.

    locatenecesita un filtro fuerte más que findporque ...

  • find(1)no necesariamente busca en todo el sistema de archivos. Por lo general, lo apunta a un subdirectorio, un padre que contiene todos los archivos en los que desea que funcione. El comportamiento típico para una locate(1)implementación es generar todos los archivos que coincidan con su patrón, dejando que se grepfiltre y así reducir su erupción al tamaño mínimo.

    (Consejo malvado: ¡ locate /probablemente obtendrá una lista de todos los archivos en el sistema!)

    Hay variantes locate(1)similares slocate(1)que restringen la salida en función de los permisos del usuario, pero esta no es la versión predeterminada de locateningún sistema operativo principal.

  • find(1)puede hacer cosas a los archivos que encuentra, además de solo encontrarlos. El operador más poderoso y ampliamente compatible es -exec, pero hay otros. En implementaciones recientes de búsqueda de GNU y BSD, por ejemplo, tiene los operadores -deletey -execdir.

  • find(1) se ejecuta en tiempo real, por lo que su salida siempre está actualizada.

    Debido a que se locate(1)basa en una base de datos actualizada horas o días en el pasado, su salida puede estar desactualizada. (Este es el problema de la memoria caché obsoleta ). Esta moneda tiene dos caras:

    1. locate puede nombrar archivos que ya no existen.

      GNU locatey mlocatetiene la -ebandera para hacer que verifique la existencia del archivo antes de imprimir el nombre de cada archivo que descubrió en el pasado, pero esto elimina algunas de las locateventajas de velocidad y no está disponible en BSD locateademás.

    2. locate no podrá nombrar los archivos que se crearon desde la última actualización de la base de datos.

    Aprende a desconfiar un poco de la locateproducción, sabiendo que puede estar mal.

    Hay formas de resolver este problema, pero no conozco ninguna implementación en uso generalizado. Por ejemplo, existe rlocate, pero parece que no funciona en ningún kernel de Linux moderno.

  • find(1) nunca tiene más privilegios que el usuario que lo ejecuta.

    Debido a que locateproporciona un servicio global a todos los usuarios en un sistema, desea que su updatedbproceso se ejecute rootpara que pueda ver todo el sistema de archivos. Esto lleva a una selección de problemas de seguridad:

    1. Ejecutar updatedbcomo root, pero hacer que su archivo de salida sea legible en todo el mundo para que locatepueda ejecutarse sin privilegios especiales. Esto expone efectivamente los nombres de todos los archivos del sistema a todos los usuarios. Esto puede ser una violación de seguridad suficiente para causar un problema real.

      BSD locatese configura de esta manera en Mac OS X y FreeBSD.

    2. Escriba la base de datos como legible solo por rooty haga locate setuidroot para que pueda leer la base de datos. Esto significa que locateefectivamente tiene que volver a implementar el sistema de permisos del sistema operativo para que no muestre archivos que normalmente no puede ver. También aumenta la superficie de ataque de su sistema, específicamente arriesgando un ataque de escalada de raíz .

    3. Cree un " locate" usuario o grupo especial para poseer el archivo de la base de datos y marque el locatebinario setuid/setgidpara ese usuario / grupo para que pueda leer la base de datos. Esto no evita los ataques de escalada de privilegios por sí mismo, pero mitiga en gran medida el daño que uno podría causar.

      mlocateestá configurado de esta manera en Red Hat Enterprise Linux .

      Sin embargo, todavía tiene un problema, porque si puede usar un depurador locateo hacer que descargue el núcleo , puede acceder a partes privilegiadas de la base de datos.

    No veo una manera de crear un locatecomando verdaderamente "seguro" , salvo ejecutarlo por separado para cada usuario en el sistema, lo que niega gran parte de su ventaja find(1).

En pocas palabras, ambos son muy útiles. locate(1)es mejor cuando solo estás tratando de encontrar un archivo en particular por nombre, que sabes que existe, pero simplemente no recuerdas dónde está exactamente. find(1)es mejor cuando tiene un área enfocada para examinar, o cuando necesita cualquiera de sus muchas ventajas.

Warren Young
fuente
Lo siento, pasé por alto el párrafo "Slocate". rlocate soluciona el problema de caché obsoleto . Es posible que desee mencionar algunas de las peculiaridades de find, como find -- "$dir" no robusto ( $dirpuede ser tomado como un predicado), no hay forma de probar los atributos de un enlace simbólico, problemas de condición de carrera ... Para mí findy locateabordar dos problemas diferentes. Hay muchos lugares donde usar find no es realista (como directorios que contienen millones de archivos). localizar es un sistema de indexación limitado a nombres de archivo.
Stéphane Chazelas
2
Las primeras implementaciones de locatefueron más o menos similares find / -type f | gzip > locate.gz, yzgrep "$1" <locate.gz
F. Hauri
@ F.Hauri: Curiosidades interesantes. Aquí hay más: GNU locateestá en el findutilspaquete, y su updatedbprograma se implementa en términos de find(1). Entonces, en ese sentido, en locate(1)realidad requiere find(1) . :)
Warren Young
1
@WarrenYoung ¿por qué hay una referencia constante a foo (1) en lugar de solo foo? ¿hay diferentes versiones, etc. de foo?
chiflado sobre natty
44
@nuttyaboutnatty: Es una antigua convención en los manuales de Unix, es decir, la sección del manual 1. Si bien es cierto que no hay find, locate, etc, en otras secciones por lo que no tiene que estar allí para eliminar la ambigüedad del mismo nombre que se utiliza en diferentes secciones del el manual (p. ej., unlink(1)vs unlink(2)), aquellos de nosotros acostumbrados a la convención lo vemos como una referencia de la página de manual.
Warren Young
35

locateutiliza una base de datos preconstruida, que debe actualizarse regularmente, mientras finditera sobre un sistema de archivos para localizar archivos.

Por lo tanto, locatees mucho más rápido que find, pero puede ser inexacto si la base de datos -puede verse como un caché- no se actualiza (ver updatedbcomando).

Además, findpuede ofrecer más granularidad, ya que puede filtrar archivos por cada atributo del mismo, mientras locateusa un patrón que coincide con los nombres de los archivos.

usuario435943
fuente
7

findno es posible que un usuario novato u ocasional de Unix lo use con éxito sin una cuidadosa lectura de la página del manual. Históricamente, algunas versiones de findni siquiera predeterminaban la -printopción, lo que aumentaba la hostilidad del usuario.

locate es menos flexible, pero mucho más intuitivo de usar en el caso común.

Russell Borogove
fuente
1
Por otro lado, localizar tiene que mantener una base de datos y ejecutarla periódicamente, por lo que la he desactivado en todos los servidores Linux que residen en nuestra red privada.
Rui F Ribeiro
2
¿Qué tiene de difícil? find . -name 'nametosearch', o -inamepara mayúsculas y minúsculas. Reemplace .con una ruta de directorio para buscar que no sea el directorio actual Allí, ese es el 90% de los requisitos de un usuario novato cubiertos sin siquiera meterse en el bloqueo de archivos. (Generalmente usaría find . -iname '*partialfilename*'y si estoy buscando /, uso lo find / -maxdepth 5 -iname '*partialname*'que reduce el tiempo de búsqueda mientras encuentro todo lo que me interesa el 90% del tiempo. Allí, el 75% de los requisitos de los usuarios intermedios.) :)
Comodín
2

Un pequeño inconveniente de localizar es que puede no estar indexando el área del sistema de archivos que le interesa. En los sistemas de escritorio Debian, por ejemplo Linux Mint 17.2, el archivo /etc/updatedb.conf está configurado para excluir ciertas áreas de consideración , incluidos / tmp, / var / spool y /home/.ecryptfs.

Ignorar /home/.ecryptfs evita que los nombres de archivo en directorios cifrados se expongan a usuarios no autorizados. Sin embargo, si su directorio de inicio está encriptado con ecryptfs, también significa que su directorio de inicio no está indexado y, por lo tanto, localizar nunca encontrará nada en su directorio de inicio. Esto puede hacer que sea en gran medida inútil para usted (lo hace para mí). Además de no encontrar resultados, el proceso actualizadob cargará periódicamente su disco sin ningún beneficio, y también podría deshabilitarse si usted es el principal o único usuario del sistema.

Jim
fuente