¿Cómo domino el comando de búsqueda de UNIX?

11

Creo que estoy bastante avanzado en mi uso de find, pero CADA vez que lo uso no puedo recordar toda la vida el método para cerrar la opción -exec. Paso mucho tiempo leyendo cada vez que lo uso. ¿Simplemente no lo estoy usando lo suficiente o espero demasiado de mí mismo? Comencemos con un ejemplo típico que me frustra.

La estructura del directorio tiene archivos con todos los permisos incorrectos, archivos ocultos, enlaces simbólicos, etc. Quiero cambiar la propiedad a un valor razonable

find . -type f -exec chown username {} \;
find . -type d -exec chown username {} \;
find . -type d -exec chgrp usergroup {} \;
find . -type f -exec chgrp usergroup {} \;

(Perdóname si el final es al revés ... Lo miré hace una hora y aún no estoy seguro)

Pero tengo miedo de ejecutarlo debido a monturas, enlaces simbólicos, etc. He hecho el mejor truco de chmod. * Y tuve que recurrir hacia arriba antes. Sé que -xdev renunciará a cruzar particiones, pero no estoy seguro de qué pasará con los archivos que se encuentran dentro de directorios que son enlaces simbólicos.

Entonces, ¿cómo se domina a esta bestia que puede matar archivos cruciales?

Actualice podando las mejores sugerencias a continuación y resumiendo:

  1. Tener un directorio de práctica vinculado y montado a otros directorios de práctica.
  2. Use xargs en lugar del comando exec no intuitivo.
  3. Use -exec echo {} por cordura y seguridad
  4. El punto y coma es especial y estás escapando, por lo tanto, el personaje de escape es el primero
  5. El comando -o puede ayudarlo a combinar criterios de selección.

Estoy un poco confundido acerca de print0 pero xargs siempre ha estado un poco en la práctica no fácil de entender a primera vista que intento evitar.

ojblass
fuente
1
Tampoco puedo recordarlo, así que simplemente lo canalizo en xargs.
resonador
2
Cuando esté satisfecho con la creación del comando correcto, considere ejecutarlo con + en lugar de \; Se ejecutará más rápido con + porque el comando exec se llamará con mucha menos frecuencia.
wzzrd
wzzrd, excelente consejo sobre el uso de + en lugar de \;
Daniel Lawson

Respuestas:

19

Bueno, en lo que respecta a la -execsintaxis, podrías hacer que te guste mucha gente, rendirte y usar xargs:

find . -type f | xargs chown username

(o la versión segura de files-with-spaces-and-other-nonsense-in-them-safe)

find . -type f -print0 | xargs -0 chown username

O, para tratar de recordar lo que debe hacer con el punto y coma, lo que necesita perforar en su cabeza es que está usando un punto y coma para terminar el comando que se -execestá ejecutando, y debe escapar del punto y coma porque tiene un punto y coma especial. es decir, a bash. Es por eso que es una barra invertida de punto y coma. Parece que la {}parte de sustitución está bien.

En cuanto a eliminar archivos, etc., si está ejecutando algo grande y peligroso como lo que está hablando, primero haga esto:

find . -type f -exec echo chown username {} \;

y revisar los resultados. Esto es básicamente una "ejecución en seco" en la que está viendo los comandos que se ejecutarían si lo dejara. Definitivamente una buena práctica. No ayudará con el .*problema, pero sabes que no debes hacer eso ahora. :)

caos
fuente
1
+! para la práctica 'echo' en seco. Siempre uso esto para un gran cambio
Steve Folly
3

Me sorprende que nadie haya mencionado la siguiente opción:

find . -type f -ok chown username {} \;

Esta sintaxis confirmará el comando antes de ejecutarlo. Funciona mejor si espera que su coincidencia sea un número relativamente pequeño de archivos porque solicitará cada uno.

Algunas respuestas mencionan xargs, pero con GNU también es innecesario:

find . -type f -exec chown username {} \+

Tenga en cuenta que el + normalmente no necesita escapar, pero es bueno adquirir el hábito de hacerlo de todos modos.

Kamil Kisiel
fuente
¿Puede explicar la naturaleza del signo más ... qué está haciendo exactamente? ¿El shell lo está procesando o el comando? Creo que voy a descargar el código fuente de gnu-find porque este es un tema interesante.
ojblass
find lo está procesando. Lea man find para obtener más información sobre esa opción.
Kamil Kisiel
3

Para eso está man: para los miembros puede ser difícil recordar cosas, por eso el comando * nix incluye páginas man. Usted sólo puede comprobar siempre la sección de acción de la página del manual de un recordatorio sobre la sintaxis: man find. Si bien las páginas de manual pueden parecer poco amigables, una vez que sea bueno para leerlas, son muy útiles.

Hacer un Front-End o Wrapper: cuando quería mejorar en GNU find, escribí un GUI front-end para find que genera comandos de búsqueda con python, glade y pygtk. Este es un buen ejercicio si quieres conocerlo realmente bien.

Tenga un directorio de práctica: por último, siempre tengo un directorio 'scrap' en mi directorio de inicio para jugar con comandos poderosos cuando algo como 'echo' no lo corta. Puede usar la expansión de shell para crear rápidamente un montón de archivos con algo como:

for i in {1..100}; do touch "$i"; done
Kyle Brandt
fuente
Extraño un directorio de práctica es algo que nunca he considerado.
ojblass
1

También puede combinar expresiones de búsqueda con los operadores '-y' y '-o'. -y está implícito:

find . -type f -name "plainfile" ...

es lo mismo que

find . -type f -and -name "plainfile" ...

El operador o puede reducir su lista de 4 comandos a 2:

find . -type d -or -type f ...

Y finalmente, no está relacionado con encontrar, pero chown también puede establecer el grupo también. Entonces, lidiando con espacios en los nombres también terminamos con:

find . -type d -or -type f -exec chown username:usergroup '{}' \;
Steve Folly
fuente
Lo que encuentre con el -o negocio. [Sic]
ojblass
@ojblass: find combina expresiones que usan 'y' o 'o', de forma predeterminada si no se especifican '-and' ni '-or', '-and' se usa implícitamente. Por lo tanto, escriba 'find -type d -type f' no encontrará nada porque nada es un directorio y un archivo.
Steve Folly
0

Al cerrar, solo pienso en usar; como con muchos lenguajes de programación y luego escapar. Solo recuerda que es necesario escapar y se te ocurre con bastante facilidad.

Garry Harthill
fuente
0

Dependiendo de la versión de find que esté utilizando, hay diferentes opciones que pueden ayudarlo. GNU find es probablemente el más poderoso y esto puede ayudarlo con su segunda pregunta (implícita)

Por ejemplo, el comportamiento predeterminado no es desreferenciar enlaces simbólicos, pero puede anular eso; y la opción -mount detiene la búsqueda de puntos de montaje

Busque en sus páginas de manual locales


fuente
0

Algunos argumentarían que la opción xargs es más rápida que la opción -exec porque no ejecutará el comando una vez para cada archivo, pero no me preocuparía por eso, excepto por trabajos masivos que requieren una cantidad de tiempo no trivial.

Personalmente, generalmente ejecuto find sin ejecutivo

find /path/to/dir -name whatever

asegúrese de que el resultado se vea correcto y luego ejecute mi comando en esa lista.

chown user:group `find /path/to/dir -name whatever`
el otro recibir
fuente
Ejemplo perfecto de cómo "no" hacer las cosas. Nombres de archivo con espacios.
Ian Kelling
Sí, ese es un problema potencial que quizás debería haber reconocido. Sin embargo, mi punto era leer el resultado de búsqueda antes de ejecutar cualquier cosa, donde detectaría espacios u otra locura de nombre de archivo.
theotherrecibir
0

Para algunos shells (no bash), escape {} para un comportamiento adecuado.

\{\} or '{}'

encontrar manual es bueno para dominar find.

Ian Kelling
fuente
No, no lo haces; find funciona bien con {} tal como están. Forman parte del comando find: son un token que se reemplaza por el resultado del comando find. Solo significan algo en bash al definir funciones o llamar variables, por lo que puede usarlas como en la pregunta original.
wzzrd
Es de la página del manual. Actualicé para decir que no es aplicable a bash.
Ian Kelling
0

Antes de hacer algo como esto, asegúrese de que el directorio en el que ejecuta este comando no esté en el mismo sistema de archivos que / usr o / etc. (de lo contrario, si tengo un enlace rígido a / etc / passwd o a / bin / sh en mi directorio de inicio, me acaba de otorgar la propiedad de esos y, como efecto secundario, ahora soy el propietario de la máquina).

Si desea recurrir a través de un directorio y compartir todos los archivos / directorios, un simple

chown -Rh usuario: usuario de grupo de usuarios /

lo haré. Hacer seguro utiliza el -H o chown seguirá los enlaces simbólicos.

Chris
fuente
No creo que esto sea multiplataforma. También falla con 247K de archivos como lo demuestra mi entorno de práctica. No estoy seguro por qué.
ojblass
Creo que ha encontrado un error más de lo que ha encontrado un problema de plataforma cruzada. ¿Qué versión y cuál es el estado de salida cuando falla? Por lo que puedo decir, primero se originó en las primeras versiones de bsd; definitivamente está en sunos 5.3 y ultrix e irix. ¿Cuántos procesa antes de fallar?
Chris
Tiene razón: funciona en AIX 5.3, AIX 5.2, pero no en AIX 4.3, NCR, HP 11, HP 10.20 o mis distribuciones DSL. En todos los casos, parece fallar en o cerca de 60k archivos.
ojblass