permission omit exclude avoid bash error-handling find file-permissions

bash - omit - permission denied in find command in linux



¿Cómo puedo excluir todos los mensajes de "permiso denegado" de "encontrar"? (18)

Respuesta simple:

find . > files_and_folders 2>&-

2>&- cierra ( - ) el descriptor de archivo de error estándar ( 2 ), por lo que todos los mensajes de error se silencian.

  • El código de salida seguirá siendo 1 si se imprimiera cualquier error de '' Permission denied ''

Respuesta robusta para find GNU:

find . -type d /! /( -readable -executable /) -prune -print -o -print > files_and_folders

Pase opciones adicionales para find que -prune (evitar descender a) pero aún así -print cualquier directorio ( -type d ) que no tenga ( /! ) -readable y de -executable , o ( -o ) -print cualquier otro archivo .

  • -readable opciones -readable y -executable son extensiones GNU, que no forman parte del find
  • Aún puede devolver '' Permission denied '' en archivos anormales / corruptos (por ejemplo, ver el informe de errores que afecta a los sistemas de archivos montados en contenedores utilizando lxcfs <v2.0.5)

Respuesta robusta que funciona con cualquier find compatible con POSIX (GNU, OSX / BSD, etc.)

{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v ''Permission denied''; [ $? = 1 ]; } 3>&2 2>&1

Use una pipeline para pasar la secuencia de error estándar a grep , eliminando todas las líneas que contienen la cadena ''Permission denied'' .

LC_ALL=C establece la configuración regional POSIX utilizando una variable de entorno , 3>&2 2>&1 1>&3 y 3>&2 2>&1 2>&- para canalizar la secuencia de error estándar a grep , y [ $? = 1 ] [ $? = 1 ] utiliza [] para invertir el código de error devuelto por grep para aproximar el comportamiento original de find .

  • También filtrará cualquier error de ''Permission denied'' debido a la redirección de salida (por ejemplo, si el archivo files_and_folders no es grabable)

Necesito ocultar todos los mensajes de permiso denegado de:

find . > files_and_folders

Estoy experimentando cuando surge tal mensaje. Necesito reunir todas las carpetas y archivos, para lo cual no surge.

¿Es posible dirigir los niveles de permiso al archivo files_and_folders ?

¿Cómo puedo ocultar los errores al mismo tiempo?


- = Para MacOS = -

Cree un nuevo comando usando alias: simplemente agregue ~ / .bash_profile line:

alias search=''find / -name $file 2>/dev/null''

y en la nueva ventana de Terminal puedes llamarlo:

$ file=<filename or mask>; search

por ejemplo:

$ archivo = etc; buscar


Canalice stderr a /dev/null usando 2> / dev / null

find . -name ''...'' 2>/dev/null


Esos errores se imprimen en la salida de error estándar (fd 2). Para filtrarlos, simplemente redirija todos los errores a / dev / null:

find . 2>/dev/null > some_file

o primero únete a stderr y stdout y luego repite esos errores específicos:

find . 2>&1 | grep -v ''Permission denied'' > some_file


Mientras que los enfoques anteriores no abordan el caso de Mac OS X porque Mac Os X no admite el interruptor -readable así es como puede evitar errores de ''Permiso denegado'' en su salida. Esto podría ayudar a alguien.

find / -type f -name "your_pattern" 2>/dev/null .

Si está utilizando algún otro comando con find , por ejemplo, para encontrar el tamaño de los archivos de cierto patrón en un directorio 2>/dev/null todavía funcionaría como se muestra a continuación.

find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$ find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$ .

Esto devolverá el tamaño total de los archivos de un patrón dado. Note el 2>/dev/null al final del comando find.


Ninguna de las respuestas anteriores funcionó para mí. Todo lo que encuentro en Internet se centra en: ocultar errores. Ninguno maneja adecuadamente el código de retorno / salida del proceso. Uso el comando find dentro de los scripts de bash para localizar algunos directorios y luego inspeccionar su contenido. Evalúo el comando encontrar éxito usando el código de salida: un valor cero funciona, de lo contrario falla.

La respuesta proporcionada anteriormente por funciona a veces. ¡Pero tengo un escenario en el que falla! Descubrí el problema y lo arreglé yo mismo. Necesito podar los archivos cuando:

it is a directory AND has no read access AND/OR has no execute access

Ver el tema clave aquí es: Y / O. Una buena secuencia de condición sugerida que leí es:

-type d ! -readable ! -executable -prune

Esto no funciona siempre. Esto significa que una poda se activa cuando una coincidencia es:

it is directory AND no read access AND no execute access

Esta secuencia de expresiones falla cuando se otorga acceso de lectura pero no hay acceso de ejecución.

Después de algunas pruebas me di cuenta de eso y cambié mi solución de script de shell a:

buen hallazgo / home * / -maxdepth 5 -follow /
/ (-type d -a ! / (-readable -a -executable /) /) -prune /
-o /
/ (-type d -a-legible -a-ejecutable -a -name "$ {m_find_name}" /) -print

La clave aquí es colocar el "no verdadero" para una expresión combinada:

has read access AND has execute access

De lo contrario no tiene acceso completo, lo que significa: podarlo. Esto demostró funcionar para mí en un escenario en el que las soluciones sugeridas anteriormente fallaron.

Proporciono a continuación detalles técnicos para preguntas en la sección de comentarios. Pido disculpas si los detalles son excesivos.

  • ¿Por qué usar el comando nice? Tengo la idea here . Inicialmente, pensé que sería bueno reducir la prioridad del proceso cuando se busca un sistema de archivos completo. Me di cuenta de que no tiene sentido para mí, ya que mi script está limitado a pocos directorios. Reduje -maxdepth a 3.
  • ¿Por qué buscar dentro de / home * /? Esto no es relevante para este hilo. Instalo todas las aplicaciones a mano a través del código fuente compilado con usuarios sin privilegios (no root). Se instalan dentro de "/ home". Puedo tener múltiples binarios y versiones conviviendo. Necesito ubicar todos los directorios, inspeccionar y hacer copias de seguridad de forma maestro-esclavo. Puedo tener más de un "/ home" (varios discos que se ejecutan dentro de un servidor dedicado).
  • ¿Por qué usar -follow? Los usuarios pueden crear enlaces simbólicos a directorios. Su utilidad depende, necesito mantener un registro de las rutas absolutas encontradas.

Para evitar solo las advertencias de permiso denegado, diga a find que ignore los archivos ilegibles recortándolos de la búsqueda. Agregue una expresión como OR a su búsqueda, como

find / /! -readable -prune -o -name ''*.jbd'' -ls

Esto dice principalmente que ( haga coincidir un archivo ilegible y elimínelo de la lista) O ( haga coincidir un nombre como * .jbd y visualícelo [con ls]) . (Recuerda que, de forma predeterminada, las expresiones son AND'' juntas a menos que uses -o.) Necesitas los -ls en la segunda expresión o, si no, find puede agregar una acción predeterminada para mostrar cualquiera de las coincidencias, que también te mostrará todos los archivos ilegibles. .

Pero si busca archivos reales en su sistema, generalmente no hay razón para buscar en / dev, que tiene muchos archivos, por lo que debe agregar una expresión que excluya ese directorio, como:

find / -mount /! -readable -prune -o -path /dev -prune -o -name ''*.jbd'' -ls

Entonces (haga coincidir el archivo ilegible y pode de la lista) O ( haga coincidir la ruta / dev y pode desde la lista) O ( haga coincidir el archivo como * .jbd y visualícelo ) .


Puedes usar el grep -v invert-match

-v, --invert-match select non-matching lines

Me gusta esto:

find . > files_and_folders cat files_and_folders | grep -v "permission denied" > files_and_folders

Debería a la magia


Redirigir el error estándar. Por ejemplo, si está utilizando bash en una máquina unix, puede redirigir el error estándar a / dev / null de esta manera:

find . 2>/dev/null >files_and_folders


Si desea iniciar la búsqueda desde la raíz "/", es probable que vea resultados como:

find: /./proc/1731/fdinfo: Permission denied find: /./proc/2032/task/2032/fd: Permission denied

Es por el permiso. Para resolver esto:

  1. Puedes usar el comando sudo find /. -name ''toBeSearched.file'' : sudo find /. -name ''toBeSearched.file'' sudo find /. -name ''toBeSearched.file'' . le pide la contraseña de superusuario, cuando ingrese la contraseña verá el resultado que realmente desea.

  2. ¡Puede usar la redirección de la salida de error estándar de (generalmente pantalla / pantalla) a algún archivo y evitar ver los mensajes de error en la pantalla! redirigir a un archivo especial / dev / null:

    find /. -name ''toBeSearched.file'' 2>/dev/null

  3. Puede usar la redirección de la salida de error estándar de (generalmente pantalla / pantalla) a la salida estándar (generalmente pantalla / pantalla), luego canalizar con el comando grep con el parámetro -v "invertir" para no ver las líneas de salida que tienen ''Permiso denegado'' pares de palabras:

    find /. -name ''toBeSearched.file'' 2>&1 | grep -v ''Permission denied''



También es una solución fácil para poner los resultados de su búsqueda en un archivo.

encontrar . -nombre ''NameOfSearchedFile'' >> results.txt



Tuve que usar:

find / -name expect 2>/dev/null

especificando el nombre de lo que quería encontrar y luego diciéndole que redirija todos los errores a / dev / null

espera ser la ubicación del programa de expectativa que estaba buscando.


Utilizar:

find . ! -readable -prune -o -print

o más generalmente

find <paths> ! -readable -prune -o <other conditions like -name> -print

  • para evitar "Permiso denegado"
  • Y NO suprimir (otros) mensajes de error
  • Y obtenga el estado de salida 0 ("todos los archivos se procesan correctamente")

Trabaja con: find (GNU findutils) 4.4.2. Fondo:

  • La prueba de lectura coincide con los archivos legibles. El el operador devuelve verdadero, cuando la prueba es falsa Y ! -readable ! -readable con los directorios no legibles (y archivos).
  • La acción -prune no desciende al directorio.
  • ! -readable -prune ! -readable -prune puede traducirse a: si el directorio no es legible, no descienda a él.
  • La prueba de -readable tiene en cuenta las listas de control de acceso y otros artefactos de permisos que la prueba de la -perm .

Vea también la página de manual find (1) para muchos más detalles.


Utilizar:

find . 2>/dev/null > files_and_folders

Esto oculta no solo los errores de Permission denied , por supuesto, sino todos los mensajes de error.

Si realmente desea mantener otros posibles errores, como demasiados saltos en un enlace simbólico, pero no los permisos denegados, entonces probablemente tenga que suponer que no tiene muchos archivos llamados ''permiso denegado'' y prueba:

find . 2>&1 | grep -v ''Permission denied'' > files_and_folders

Si solo desea filtrar el error estándar, puede usar la construcción más elaborada:

find . 2>&1 > files_and_folders | grep -v ''Permission denied'' >&2

La redirección de E / S en el comando de find es: 2>&1 > files_and_folders | . La tubería redirige la salida estándar al comando grep y se aplica primero. El 2>&1 envía un error estándar al mismo lugar que la salida estándar (la tubería). Las > files_and_folders envían una salida estándar (pero no un error estándar) a un archivo. El resultado neto es que los mensajes escritos a error estándar se envían por la tubería y la salida regular de la find se escribe en el archivo. El grep filtra la salida estándar (puede decidir qué tan selectivo desea que sea, y es posible que tenga que cambiar la ortografía según la configuración regional y el O / S) y el final >&2 significa que los mensajes de error supervivientes (escritos en la salida estándar) ir al error estándar una vez más. La redirección final podría considerarse como opcional en el terminal, pero sería una muy buena idea usarla en un script para que aparezcan mensajes de error en el error estándar.

Existen infinitas variaciones en este tema, dependiendo de lo que quieras hacer. Esto funcionará en cualquier variante de Unix con cualquier derivado de shell Bourne (Bash, Korn, ...) y cualquier versión compatible con POSIX de find .

Si desea adaptarse a la versión específica de find que tiene en su sistema, puede haber opciones alternativas disponibles. GNU find en particular, tiene una gran variedad de opciones que no están disponibles en otras versiones; consulte la respuesta actualmente aceptada para un conjunto de opciones de este tipo.


utilizar

sudo find / -name file.txt

Es estúpido (porque elevas la búsqueda) y no seguro, pero mucho más corto para escribir.


Nota:
* Esta respuesta probablemente sea más profunda que las garantías del caso de uso, y find 2>/dev/null puede ser lo suficientemente bueno en muchas situaciones. Todavía puede ser de interés para una perspectiva multiplataforma y para su discusión de algunas técnicas avanzadas de shell con el fin de encontrar una solución lo más robusta posible, incluso aunque los casos a los que se puede proteger pueden ser en gran medida hipotéticos.
* Si su sistema está configurado para mostrar mensajes de error localizados , aplique el prefijo de find a continuación con LC_ALL=C ( LC_ALL=C find ... ) para asegurarse de que se notifiquen los mensajes en inglés , de modo que grep -v ''Permission denied'' funcione según lo previsto . Sin embargo, invariablemente, cualquier mensaje de error que se muestre también estará en inglés.

Si su shell es bash o zsh , hay una solución que es robusta a la vez que es razonablemente simple , utilizando solo las funciones de find compatibles con POSIX ; Si bien bash no forma parte de POSIX, la mayoría de las plataformas modernas de Unix vienen con él, lo que hace que esta solución sea ampliamente portátil:

find . > files_and_folders 2> >(grep -v ''Permission denied'' >&2)

Nota: hay una pequeña posibilidad de que algunos de los resultados de grep puedan llegar después de que se complete la find , ya que el comando general no espera a que el comando dentro de >(...) finalice. En bash , puedes prevenir esto agregando | cat | cat a la orden.

  • >(...) es una sustitución del proceso de salida (rara vez se usa) que permite redireccionar la salida (en este caso, la salida stderr ( 2> ) al comando interno dentro del comando >(...) .
    Además de bash y zsh , ksh admite en principio , pero al intentar combinarlos con la redirección desde stderr , como se hace aquí ( 2> >(...) ), parece ser ignorado en silencio (en ksh 93u+ ) .

    • grep -v ''Permission denied'' filtra ( -v ) todas las líneas (de la secuencia stderr del comando find ) que contienen la frase Permission denied y envía las líneas restantes a stderr ( >&2 ).

Este enfoque es:

  • robusto : grep solo se aplica a los mensajes de error (y no a una combinación de rutas de archivos y mensajes de error, lo que podría dar lugar a falsos positivos), y los mensajes de error distintos de los que no tienen permiso se transfieren a stderr.

  • sin efectos secundarios : el código de salida de find se conserva: la imposibilidad de acceder al menos a uno de los elementos del sistema de archivos encontrados da como resultado el código de salida 1 (aunque eso no le dirá si se produjeron errores distintos a los permisos denegados (también) ).

Soluciones compatibles con POSIX:

Las soluciones totalmente compatibles con POSIX tienen limitaciones o requieren trabajo adicional.

Si la salida de find debe capturarse en un archivo de todos modos (o eliminarse por completo), entonces la solución basada en la tubería de la respuesta de Jonathan Leffler es simple, robusta y compatible con POSIX:

find . 2>&1 >files_and_folders | grep -v ''Permission denied'' >&2

Tenga en cuenta que el orden de las redirecciones importa: 2>&1 debe aparecer primero .

La captura de la salida de la salida estándar en un archivo al principio permite que 2>&1 envíe solo mensajes de error a través de la canalización, con lo que grep puede operar sin ambigüedades.

El único inconveniente es que el código de salida general será el comando grep ''s , no find ''s, que en este caso significa: si no hay errores en absoluto o solo los errores de permiso denegado, el código de salida será 1 ( falla de señalización) de lo contrario (errores distintos de los permisos denegados) 0 - que es lo contrario de la intención.
Dicho esto, el código de salida de find rara vez se utiliza de todos modos , ya que a menudo transmite poca información más allá de un error fundamental , como pasar una ruta inexistente.
Sin embargo, el caso específico de que solo algunas de las rutas de entrada sean inaccesibles debido a la falta de permisos se refleja en el código de salida de find (en GNU y BSD): si se produce un error de denegación de permisos para cualquiera de los archivos procesados , el código de salida se establece en 1 .

La siguiente variación aborda que:

find . 2>&1 >files_and_folders | { grep -v ''Permission denied'' >&2; [ $? -eq 1 ]; }

Ahora, el código de salida indica si ocurrió algún error distinto al Permission denied : 1 caso afirmativo, 0 caso contrario.
En otras palabras: el código de salida ahora refleja la verdadera intención del comando: se informa sobre el éxito ( 0 ), si no se produjo ningún error o solo se produjeron errores de denegación de permisos.
Esto es posiblemente incluso mejor que simplemente pasar el código de salida de Find a través, como en la solución en la parte superior.

gniourf_gniourf en los comentarios propone una generalización (aún compatible con POSIX) de esta solución mediante redirecciones sofisticadas , que funciona incluso con el comportamiento predeterminado de imprimir las rutas de archivo a la salida estándar :

{ find . 3>&2 2>&1 1>&3 | grep -v ''Permission denied'' >&3; } 3>&2 2>&1

En resumen: el descriptor de archivo personalizado 3 se usa para intercambiar temporalmente stdout ( 1 ) y stderr ( 2 ), de modo que solo los mensajes de error se pueden canalizar a grep través de stdout.

Sin estas redirecciones, tanto los datos (rutas de archivo) como los mensajes de error se enviarán a grep través de stdout, y grep no podrá distinguir entre el mensaje de error Permission denied y un archivo (hipotético) cuyo nombre contenga la frase Permission denied .

Sin embargo, como en la primera solución, el código de salida que se informa será grep ''s, no find '' s, pero se puede aplicar la misma solución anterior.

Notas sobre las respuestas existentes:

  • Hay varios puntos a tener en cuenta sobre la respuesta de Michael Brux , find . ! -readable -prune -o -print find . ! -readable -prune -o -print find . ! -readable -prune -o -print :

    • Requiere find GNU ; En particular, no funcionará en macOS. Por supuesto, si solo necesita el comando para trabajar con GNU find , esto no será un problema para usted.

    • Algunos errores de Permission denied aún pueden aparecer: find ! -readable -prune find ! -readable -prune informa de dichos errores para los elementos secundarios de los directorios para los que el usuario actual tiene permiso r , pero carece del permiso x (ejecutable). La razón es que debido a que el directorio en sí es legible, -prune no se ejecuta, y el intento de descender a ese directorio genera los mensajes de error. Dicho esto, el caso típico es que falte el permiso r .

    • Nota: El siguiente punto es una cuestión de filosofía y / o caso de uso específico, y puede decidir que no es relevante para usted y que el comando se adapta bien a sus necesidades, especialmente si lo único que hace es imprimir los caminos:

      • Si conceptualiza el filtrado de los mensajes de error con permiso denegado una tarea separada que desea poder aplicar a cualquier comando de find , entonces el enfoque opuesto de prevenir de forma proactiva los errores de permiso denegado requiere la introducción de "ruido" en el comando de find , que También introduce complejidad y trampas lógicas.
      • Por ejemplo, el comentario más votado sobre la respuesta de Michael (en el momento de escribir esto) intenta mostrar cómo extender el comando incluyendo un filtro de nombre, de la siguiente manera:
        find . ! -readable -prune -o -name ''*.txt''
        Sin embargo, esto no funciona como se esperaba, ya que se requiere la acción de -print final (se puede encontrar una explicación en esta respuesta ). Tales sutilezas pueden introducir errores.
  • La primera solución en la respuesta de Jonathan Leffler , find . 2>/dev/null > files_and_folders find . 2>/dev/null > files_and_folders , como él mismo afirma, silencia ciegamente todos los mensajes de error (y la solución es incómoda y no completamente robusta, como también explica). Hablando de manera pragmática , sin embargo, es la solución más sencilla , ya que puede contentarse con asumir que todos los errores estarán relacionados con el permiso.

  • respuesta de la niebla , sudo find . > files_and_folders sudo find . > files_and_folders , es conciso y pragmático, pero mal aconsejado para otra cosa que no sea simplemente imprimir nombres de archivos , por razones de seguridad: porque se está ejecutando como el usuario root , "corre el riesgo de que todo su sistema esté desordenado por un error al buscar o una versión malintencionada, o una invocación incorrecta que escribe algo inesperadamente, lo que no podría suceder si se ejecutara con los privilegios normales "(de un comentario sobre la respuesta de tripleee por tripleee ).

  • La segunda solución en la respuesta de viraptor , find . 2>&1 | grep -v ''Permission denied'' > some_file find . 2>&1 | grep -v ''Permission denied'' > some_file find . 2>&1 | grep -v ''Permission denied'' > some_file corre el riesgo de falsos positivos (debido a que envía una mezcla de stdout y stderr a través de la tubería), y potencialmente, en lugar de informar errores no permitidos a través de stderr, los captura junto al rutas de salida en el archivo de salida.