Quería ejecutar de forma recursiva chmod go+w
en 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, find
asume 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 exec
se ejecuta solo si la primera name
condició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, -print
vinculado 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, -o
es elsolooperador.