Prefacio: entiendo la diferencia entre -exec {} \;
& -exec {} +
. Tampoco tengo un problema como tal , solo tengo curiosidad por la semántica de find
.
Al finalizar el -exec
argumento con en +
lugar de ;
, necesitamos terminar esto con {} +
, por ejemplo:
# FreeBSD find
$ find . -type f -exec cp {} /tmp +
find: -exec: no terminating ";" or "+"
# GNU find is even more cryptic:
$ find: missing argument to `-exec'
Usar ;
en estos ejemplos en lugar de +
funciona bien (pero obviamente hace algo más).
Desde POSIX :
-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +
... Solo un <plus-sign> que sigue inmediatamente a un argumento que contiene solo los dos caracteres "
{}
" debe puntuar el final de la expresión primaria. Otros usos del <plus-sign> no se tratarán como especiales.
En otras palabras, cuando se usa +
, el comando debe terminar con {} +
.
¿Por qué es esto? ¿Y por qué solo con el +
y no con el ;
? Al principio pensé que tal vez evitaría conflictos con los nombres de archivo que contienen un +
, pero ¿los nombres de archivo con un ;
parecen funcionar bien? Me resulta difícil creer que esta limitación sea arbitraria ...
The "-exec ... {} +" syntax adopted was a result of
IEEE PASC Interpretation 1003.2 #210
y en ese documento encontrará más detalles, por ejemplo:Note that the "+" is only treated as special if it immediately follows "{}". This minimises the chances of causing problems with existing uses of "+" as an argument with "-exec".
Respuestas:
La justificación dada en la especificación POSIX es:
PASC Interpretation 1003.2 # 210 entra en más detalles sobre la historia de
-exec … {} +
. Existía en varios sistemas Unix antes de que fuera adoptado por POSIX; el informe de defectos lo remonta a SVR4 (donde estaba en gran parte indocumentado). El informe de defectos justifica que el cambio incompatible tenga poco impacto en la práctica:Aunque agregar soporte para
-exec … {} +
rompería algunas aplicaciones conformes, como el ejemplo anterior, hay menos de estas que si-exec … {} … +
se permitieran.Otra razón, tal vez, para restringir
{}
a ser el último argumento es la facilidad de implementación. Si{}
se permitiera en cualquier lugar de la lista de argumentos-exec
, elfind
programa tendría que construir la línea de comando copiando los argumentos estáticos, luego la parte variable y luego otra parte estática. Esto dificultaría la construcción de la lista de argumentos y el límite de tamaño. La dificultad es mínima, pero a los implementadores les gusta cortar esquinas. Soportar múltiples instancias sustituibles de{}
(si-exec {} foo +
es para trabajar, lógicamente se puede esperar que eso-exec {} foo {} +
también) sería significativamente más difícil.fuente