Diferentes comportamientos entre find -exec y canalización a través de xargs

Diferentes comportamientos entre find -exec y canalización a través de xargs

Quería ejecutar de forma recursiva chmod go+wen una carpeta particular que incluye archivos ocultos, y primero intenté

find . -name ".*" -o -name "*" -exec chmod go+w {} \;

pero descubrí que no afectaba los archivos ocultos. Para controlarme, corrí solo

find . -name ".*" -o -name "*"

y se enumeraron los archivos ocultos. También noté que si excluía la -o -name "*"parte, modificaría los archivos ocultos (pero excluiría los no ocultos, por supuesto). Mi último intento fue usar xargs en su lugar.

find . -name ".*" -o -name "*" | xargs chmod go+w

que finalmente funcionó como se esperaba. ¿Qué estoy haciendo mal en el primer fragmento?

Red Hat Enterprise Linux Server versión 6.8 (Santiago)

GNU bash, versión 4.3.42(1) (x86_64-unknown-linux-gnu)

Respuesta1

La solución es unir las dos pruebas de nombres con sus pares.

Para ilustrar esto, consideremos un directorio con tres archivos normales:

$ ls -a
.  ..  .hidden1  .hidden2  not_hidden

Ahora, veamos el comando original:

$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden

Sólo se encuentra el archivo no oculto.

A continuación, agreguemos padres para agrupar las dos pruebas de nombres:

$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2

Se encuentran todos los archivos.

La solución es utilizar padres.

Más detalles

En el comando original, no hay ningún operador entre -name "*"y -exec ... \;. En consecuencia, findasume el operador predeterminado que es lógico-y. Debido a que el and lógico se vincula más estrechamente que el lógico o ( -o), esto significa que el comando se interpreta como:

find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)

Esto significa que execse ejecuta solo si la primera namecondición no coincide.

Para obtener más información, consulte laOPERADORESsección en man find.

¿Qué pasa sin-exec

Intentemos usar un simple -print:

$ find . -name ".*" -o -name "*" -print
./not_hidden

Como puede ver, -printvinculado a -name "*"la lógica implícita, y como se indicó anteriormente.

Pero considere lo que sucede sin que se especifique ninguna acción:

$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2

Aquí se encontraron todos los archivos. La razón es que, en esta versión, -oes elsolooperador.

información relacionada