Por que 'find -exec cmd {} +' precisa terminar em '{} +'?

7

Prefácio: Eu entendo a diferença entre -exec {} \; & %código%. Eu também não tenho um problema como tal , estou apenas curioso sobre a semântica de -exec {} + .

Ao finalizar o argumento find com -exec em vez de + , precisamos para terminar com ; , por exemplo:

# 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 {} + nesses exemplos em vez de ; funciona bem (mas obviamente faz outra coisa).

De POSIX :

-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +

...   Only a <plus-sign> that immediately follows an argument containing only the two characters "{}" shall punctuate the end of the primary expression.  Other uses of the <plus-sign> shall not be treated as special.

Em outras palavras, ao usar o + , o comando precisa para terminar com + .

Por que isso? E por que apenas com o {} + e não com o + ? No começo eu pensei em evitar conflitos com nomes de arquivos que contêm ; , mas nomes de arquivos com + parecem funcionar bem? Eu acho difícil acreditar que essa limitação é arbitrária ...

    
por Martin Tournoij 15.01.2015 / 22:35

1 resposta

5

A justificativa fornecida na especificação POSIX é:

The "-exec ... {} +" syntax adopted was a result of IEEE PASC Interpretation 1003.2 #210. It should be noted that this is an incompatible change to the ISO/IEC 9899:1999 standard. For example, the following command prints all files with a '-' after their name if they are regular files, and a '+' otherwise:

find / -type f -exec echo {} - ';' -o -exec echo {} + ';'

The change invalidates usage like this. Even though the previous standard stated that this usage would work, in practice many did not support it and the standard developers felt it better to now state that this was not allowable.

Interpretação PASC 1003.2 # 210 entra em mais detalhes sobre o histórico de -exec … {} + . Existia em vários sistemas Unix antes de ser adotado pelo POSIX; o relatório de defeitos o rastreia até SVR4 (onde era em grande parte não documentado). O relatório de defeito justifica a alteração incompatível como tendo pouco impacto na prática:

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".

Embora adicionar suporte para -exec … {} + possa quebrar alguns aplicativos em conformidade, como o exemplo acima, há menos deles do que se -exec … {} … + fosse permitido.

Outra razão, talvez, para restringir {} a ser o último argumento é a facilidade de implementação. Se {} fosse permitido em qualquer lugar na lista de argumentos para -exec , o programa find teria que criar a linha de comando copiando os argumentos estáticos, a parte variável e outra parte estática. Isso dificultaria a construção da lista de argumentos e a contabilização do limite de tamanho. A dificuldade é mínima, mas os implementadores gostam de cortar custos. O suporte a múltiplas instâncias substituíveis de {} (se -exec {} foo + for funcionar, pode ser logicamente esperado que -exec {} foo {} + também seria) seria significativamente mais difícil.

    
por 16.01.2015 / 02:43