Чому 'find -exec cmd {} +' повинен закінчуватися на '{} +'?


11

Передмова: Я розумію різницю між -exec {} \;& -exec {} +. Я також не проблема , як такої , я просто цікаво про семантику find.


Закінчуючи -execаргумент +замість ;, нам потрібно закінчити це {} +, наприклад:

# FreeBSD find
$ find . -type f -exec cp {} /tmp +
find: -exec: no terminating ";" or "+"

# GNU find is even more cryptic:
$ find: missing argument to `-exec'

Використання ;в цих прикладах замість цього +працює чудово (але, очевидно, робить щось інше).

Від POSIX :

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

... Тільки <plus-sign>, який негайно слідує за аргументом, що містить лише два символи, " {}" пунктуаціює кінець основного виразу. Інші способи використання <plus-sign> не розглядаються як особливі.

Іншими словами, при використанні +команди команда повинна закінчуватися {} +.

Чому це? І чому тільки з тим, +а не тим ;? Спочатку я думав, можливо, щоб уникнути конфліктів із іменами файлів, які містять +, але назви файлів, ;схоже, спрацюють нормально? Мені важко повірити, що це обмеження є довільним ...


3
FWIW, на сторінці POSIX також зазначено, що The "-exec ... {} +" syntax adopted was a result of IEEE PASC Interpretation 1003.2 #210і в цьому документі ви знайдете більше деталей, наприклад: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".
don_crissti

Відповіді:


5

Обгрунтування дано в специфікації POSIX є:

"-exec ... {} +"Синтаксис прийнятий був результатом IEEE PASC інтерпретації 1003,2 # 210. Слід зазначити, що це несумісна зміна стандарту ISO / IEC 9899: 1999. Наприклад, наступна команда друкує всі файли з '-'назвою після їх імені, якщо вони є звичайними файлами, і '+'іншим чином:

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

Ця зміна визнає недійсним використання. Незважаючи на те, що попередній стандарт зазначав, що це використання буде працювати, на практиці багато хто не підтримує його, і розробники стандартів вважають, що краще заявити, що це неможливо.

Інтерпретація PASC 1003.2 # 210 детальніше розповідає про історію Росії -exec … {} +. Він існував на кількох системах Unix до того, як був прийнятий POSIX; звіт про дефекти відносить його до SVR4 (де він значною мірою був недокументований). Звіт про дефекти виправдовує несумісні зміни як такі, що мало впливають на практиці:

Зауважте, що "+" вважається спеціальним лише у тому випадку, якщо воно одразу після "{}". Це мінімізує шанси викликати проблеми з існуючим використанням "+" як аргументу з "-exec".

Хоча додавання підтримки -exec … {} +може порушити деякі відповідні додатки, наприклад, наведений вище приклад, їх менше, ніж якби -exec … {} … +було дозволено.

Можливо, ще однією причиною обмеження {}останнього аргументу є простота реалізації. Якщо це {}було дозволено де-небудь у списку аргументів -exec, findпрограма повинна була б створити командний рядок, скопіювавши статичні аргументи, потім змінну частину, потім іншу статичну частину. Це ускладнить побудову списку аргументів та облік обмеження розміру. Складність мінімальна, але виконавці люблять вирізати кути. Підтримка декількох змінних екземплярів {}(якщо -exec {} foo +це буде працювати, то логічно можна очікувати, що -exec {} foo {} +так само) буде значно важче.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.