Використовуючи наступну команду, чи не могли б хто-небудь пояснити, яка саме мета для закінчення фігурних дужок ({}) та знаку плюс (+)?
І як би команда діяла по-іншому, якби вони були виключені з команди?
find . -type d -exec chmod 775 {} +
Використовуючи наступну команду, чи не могли б хто-небудь пояснити, яка саме мета для закінчення фігурних дужок ({}) та знаку плюс (+)?
І як би команда діяла по-іншому, якби вони були виключені з команди?
find . -type d -exec chmod 775 {} +
Відповіді:
Фігурні дужки будуть замінені результатами findкоманди, і chmodзапуск буде виконуватися на кожному з них. В +марці findнамагається працювати як кілька команд , як це можливо (так, chmod 775 file1 file2 file3на відміну від chmod 755 file1, chmod 755 file2, chmod 755 file3). Без них команда просто видає помилку. Це все пояснено у man find:
-exec command ;
Виконати команду ; вірно, якщо статус 0 повернуто. Усі наступні аргументи
findповинні бути аргументами команди, поки аргумент, що складається з ';'. Рядок '{}' замінюється поточним ім'ям файлу, який обробляється скрізь, де він зустрічається в аргументах команди, а не тільки в аргументах, де він один, як у деяких версіяхfind. …
-exec command {} +
Цей варіант
-execдії виконує задану команду на вибраних файлах, але командний рядок будується додаванням кожного вибраного імені файлу в кінці; загальна кількість викликів команди буде значно меншою, ніж кількість відповідних файлів. …
На додаток до відповіді тердона,
-exec …треба закінчувати крапкою з комою ( ;) або знаком плюс ( +). Кома спеціальний символ в оболонці (або, принаймні, кожен обстрілювати я коли - небудь використав), тому, якщо він буде використовуватися як частина findкоманди , він повинен бути екранований або цитований ( \;, ";"або ';').З -exec … ;, {}рядок може з'являтися в команді будь-яку кількість разів, включаючи нуль або два або більше, в будь-якому положенні.
Дивіться це
для прикладу того, чому ви можете зробити це -execбез використання {}.
Наявність двох або більше виступів корисно головним чином, оскільки, принаймні, у деяких версіях find, {}не потрібно бути словом само по собі; він може мати інші символи на початку чи в кінці; наприклад,
find . -type f -exec mv {} {}.bak ";"
З -exec … +, {}рядок повинен бути останнім аргументом перед +. Така команда
find . -name "*.bak" -exec mv {} backup_folder +
приводить до загадкового find: missing argument to ‘-exec’повідомлення про помилку.
Вирішення цього, характерного для команд cpта mvкоманд, є
find . -name "*.bak" -exec mv -t backup_folder {} +
або
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
{}Повинно бути слово само по собі; він не може мати інших символів на початку чи в кінці. І, принаймні, у деяких версіях програми findви можете мати не одну {}.
Санітарна примітка: Ви можете сказати
знайти. -name "* .sh" -тип f -executable -exec {} необов'язкові аргументи тут ";"
для запуску кожного зі своїх сценаріїв. Але
знайти. -name "* .sh" -тип f -executable -exec {} +
запускає один із ваших сценаріїв, імена всіх інших як параметри. Це схоже на висловлювання
./*.sh
як команда оболонки, за винятком випадків find, не гарантує сортування її результатів, тому вам не гарантується запуск aaa.sh
(ваш алфавітний перший *.shфайл), як це було б із запуском ./*.sh.
Аспект, findякий може бути не зовсім зрозумілим для початківців, полягає в тому, що командний рядок - це фактично виконуваний вислів на мавній мові. Наприклад,
find . -name "*.sh" -type f -executable -print
засоби
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
або, просто,
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
Деякі -ключові слова є і виконаною дією, і тестом. Зокрема, це стосується -exec … ;; наприклад,
find . -type f -exec grep -q cat {} ";" -print
перекладається на
для кожного файлу
якщо це звичайний файл (тобто не каталог)
потім
виконати grep -q cat filename
якщо процес успішний (тобто, виходить зі статусом 0)
потім
роздрукувати ім'я файлу
закінчується, якщо
закінчується, якщо
кінцева петля
який буде друкувати імена всіх файлів, що містять рядок " cat". І, хоча це щось, що grepможна зробити самостійно (за допомогою -l(нижнього регістру L) опції), це може бути корисно використовувати findдля пошуку файлів, що містять певний рядок І мають певний розмір І належать певному власнику І були змінені в певний часовий діапазон,….
Однак це не працює -exec … +. Оскільки -exec … +виконується одна команда для декількох файлів, не має сенсу використовувати її як логічну умову всередині for each file …циклу.
findяк правило, виходить зі статусом виходу 0, якщо ви не наводите його недійсні аргументи, або якщо він не зустрічає каталог, який він не може прочитати. Навіть якщо програма, яку ви виконуєте, не працює (виходить із ненульовим статусом виходу),
findвийде зі статусом виходу 0.
За винятком випадків, коли програма, яку ви виконуєте зі -exec … +збоєм (виходить із ненульовим статусом виходу),
findвийде з ненульовим статусом виходу.На додаток до мільйона версій find(1)
та тестування того, що findнасправді працює в декількох системах,
Технічні вимоги до відкритої групи випуску 7, видання 2013 року
надали частину інформації про те, що findпотрібно, що може, а що не потрібно робити.
... -exec mv {} {}.bak ...не мав гарантії працювати, як очікувалося, у всіхfindреалізаціях. Стандартні стани POSIX{}повинні з'являтися окремо, щоб завжди їх розпізнавати, інакше поведінка вільна, щоб символи залишалися незмінними або замінювали їх на ім'я шляху. У першому випадку вся ваша команда фактично видалить усі файли, але останній знайдений ...