Usando el siguiente comando, ¿podría alguien explicar cuál es exactamente el propósito de las llaves ({}) y el signo más (+)?
¿Y cómo funcionaría el comando de manera diferente si fueran excluidos del comando?
find . -type d -exec chmod 775 {} +
Las llaves se reemplazarán por los resultados del find
comando y chmod
se ejecutarán en cada una de ellas. Las +
marcas find
intentan ejecutar comandos como pocos como sea posible (por lo que, chmod 775 file1 file2 file3
a diferencia de chmod 755 file1
, chmod 755 file2
, chmod 755 file3
). Sin ellos, el orden de la misma da un error. Todo esto se explica en man find
:
-exec command ;
Ejecutar comando ; verdadero si se devuelve el estado 0. Todos los siguientes argumentos
find
se consideran argumentos del comando hasta que se encuentre un argumento que consista en ';
'. La cadena '{}
' se sustituye por el nombre del archivo actual está procesando todas partes se produce en los argumentos para el comando, no sólo en los argumentos en los que está solo, ya que en algunas versiones defind
. ...
-exec command {} +
Esta variante de la
-exec
acción ejecuta el comando especificado en los archivos seleccionados, pero la línea de comando se construye agregando cada nombre de archivo seleccionado al final; El número total de invocaciones del comando será mucho menor que el número de archivos coincidentes. ...
Además de la respuesta de terdon,
-exec …
debe terminar con un punto y coma bien ( ;
) o un signo más ( +
). Punto y coma es un carácter especial en el shell (o, al menos, todos los depósitos que he usado), por lo que, si se va a utilizar como parte del find
comando , que debe ser escapado o citado ( \;
, ";"
o ';'
).Con -exec … ;
, la {}
cadena puede aparecer cualquier número de veces en el comando, incluido cero , o dos o más, en cualquier posición.
Ver este
un ejemplo de por qué es posible que desee hacerlo -exec
sin utilizar {}
.
Tener dos o más apariencias es útil principalmente porque, en (al menos) algunas versiones de find
, el {}
no necesita ser una palabra en sí misma; puede tener otros personajes al principio o al final; p.ej,
find . -type f -exec mv {} {}.bak ";"
Con -exec … +
, la {}
cadena debe aparecer como el último argumento ante el +
. Un comando como
find . -name "*.bak" -exec mv {} backup_folder +
da como resultado el enigmático find: missing argument to ‘-exec’
mensaje de error.
Una solución para este que es específico para el cp
y mv
comandos es
find . -name "*.bak" -exec mv -t backup_folder {} +
o
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
El {}
debe ser una palabra por sí misma; no puede tener otros personajes al principio o al final. Y, en (al menos) algunas versiones de find
, no puede tener más de una {}
.
Una nota de cordura: Usted puede decir
encontrar . -name "* .sh" type f -executable -exec {} argumentos opcionales aquí ";"
para ejecutar cada una de las secuencias de comandos. Pero
encontrar . -name "* .sh" -tipo f -executable -exec {} +
ejecuta uno de sus scripts, con los nombres de todos los demás como parámetros. Esto es similar a decir
./*.sh
como un comando de shell, excepto find
que no garantiza que clasifique sus resultados, por lo que no se garantiza que se ejecute aaa.sh
(su primer *.sh
archivo alfabéticamente ) como lo estaría con la ejecución ./*.sh
.
Un aspecto de find
eso puede no estar perfectamente claro para los principiantes es que la línea de comando es, efectivamente, una declaración ejecutable en un lenguaje arcano. Por ejemplo,
find . -name "*.sh" -type f -executable -print
medio
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
o simplemente,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Algunas de las -
palabras clave son tanto una acción ejecutable como una prueba. En particular, esto es cierto para -exec … ;
; por ejemplo,
find . -type f -exec grep -q cat {} ";" -print
se traduce en
para cada archivo si es un archivo simple (es decir, no un directorio) luego ejecutar grep -q gato de nombre de archivo si el proceso tiene éxito (es decir, sale con el estado 0) luego imprimir el nombre del archivo terminara si terminara si bucle final
que imprimirá los nombres de todos los archivos que contienen la cadena “ cat
”. Y, si bien esto es algo que grep
puede hacer por sí mismo (con la opción -l
(en minúsculas L
)), puede ser útil usarlo find
para buscar archivos que contengan una determinada cadena Y tengan un cierto tamaño Y sean propiedad de un determinado propietario Y fueron modificados en un cierto rango de tiempo, ...
Sin embargo, esto no funciona -exec … +
. Dado que -exec … +
ejecuta un comando para varios archivos, no tiene sentido usarlo como una condición lógica dentro de un for each file …
bucle.
find
generalmente sale con un estado de salida de 0 a menos que le des argumentos inválidos o encuentre un directorio que no puede leer. Incluso si un programa que ejecuta falla (sale con un estado de salida distinto de cero),
find
saldrá con un estado de salida de 0.
Excepto si un programa que ejecuta con -exec … +
falla (sale con un estado de salida distinto de cero),
find
saldrá con un estado de salida distinto de cero.Además de un millón de versiones find(1)
y pruebas de lo que find
realmente hace en un par de sistemas, el
número 7 de la edición de especificaciones de Open Group Base, 2013
proporcionó información sobre lo que find
debe, puede y no debe hacer.
... -exec mv {} {}.bak ...
no es garantizado al trabajo como se esperaba con todas lasfind
implementaciones. Los estados estándar POSIX{}
deben aparecer solos para ser siempre reconocidos, de lo contrario el comportamiento es libre de mantener los caracteres sin cambios o reemplazarlos por el nombre de ruta. En el primer caso, todo su comando esencialmente eliminará todos los archivos, pero el último encontrado ...