¿Cómo "buscar" mientras se siguen enlaces simbólicos específicos en Linux?

¿Cómo "buscar" mientras se siguen enlaces simbólicos específicos en Linux?

Me gustaría buscar findarchivos (con características similares), pero seguir y seguir solo enlaces simbólicos específicos (por coincidencia de patrones).

Aparentemente findno puede manejarlo por sí solo: no hay ninguna opción para configurar el comportamiento de seguimiento del enlace simbólico; y un find -Lbloqueo ingenuo que se activa fácilmente (o que es extremadamente lento).

Respuesta1

La última oración de la pregunta sugiere que el problema no está en seguir enlaces simbólicos en general (y, por ejemplo, aplicar -neweral enlace simbólico en un caso, mientras que al objetivo en otro caso), sino en seguir enlaces simbólicos.a directoriosy así descender donde no quieres.

Porespecificación, finddetectará bucles infinitos, por lo que no debería ocurrir un bloqueo activo. La pérdida de recursos (incluido el tiempo) puede ser un problema y entiendo su preocupación.

En primer lugar, utilice -Lpara permitir findseguir los enlaces simbólicos que desea que siga. Entonces necesitas una forma de detectar otros enlaces simbólicos.

Nunca find -L -type les cierto, pero puede detectar enlaces simbólicos -exec test -L {} \;(recuerde -exec … \;que también es una prueba, tiene éxito si el comando interno sale con el estado 0). De esta manera aún puedes aplicar algunas pruebas específicamente a los enlaces simbólicos y -prune(o no) en consecuencia.

Por ejemplo, el siguiente comando descenderá solo enlaces simbólicos cuyos nombres comiencen fooo terminen con bar:

find -L . -exec test -L {} \; ! \( -name 'foo*' -o -name '*bar' \) -prune -o -print

Cualquier expresión que quisieras originalmente, colócala después -prune -o. En el comando anterior, la expresión "original" es -print. Recuerde -execque suprime el implícito -print, por lo que si lo necesita -print, agréguelo explícitamente (como lo hicimos nosotros).

Tenga en cuenta que -nameprueba el nombre del enlace simbólico. Si desea probar el nombre del objetivo, entonces necesita realpath, posiblemente basename, algún código de shell; ejemplo:

find -L . -exec test -L {} \; -exec sh -c '
   case "$(basename "$(realpath "$1")")" in
      baz* ) exit 0 ;;
      *qux ) exit 1 ;;
   esac
   exit 0
' find-sh {} \; -prune -o -print

El comando anterior creará -prunecualquier enlace simbólico a cualquier archivo cuyo nombre comience con baz, pero descenderá los enlaces simbólicos a directorios con nombres que terminen en qux(a menos que comiencen con baz) y finalmente -prunea todos los demás enlaces simbólicos.

Notas:

  • realpathy basenameno son portátiles.
  • realpathresuelve todos los enlaces simbólicos.
  • El comportamiento en caso de un enlace simbólico roto puede ser o no el esperado.
  • Invocar un archivo separado testpara cada archivo afectará el rendimiento, pero no he encontrado una manera mejor. Invocar sh, realpathy basenametambién es malo en este asunto, pero aquí ocurre solo para enlaces simbólicos, por lo que en la mayoría de los casos el impacto será limitado.
  • find-shse explica aquí:¿Cuál es el segundo pez sh -c 'some shell code' sh?
  • En los ejemplos, las rutas de acceso que obtienen -pruned no serán -printed. Cambie el fragmento final a -prune -false -o -printy se imprimirán. Verexplicación; Hay una alternativa portátil -falseen caso de que la necesites.

información relacionada