Використовуючи наступну команду, чи не могли б хто-небудь пояснити, яка саме мета для закінчення фігурних дужок ({}) та знаку плюс (+)?
І як би команда діяла по-іншому, якби вони були виключені з команди?
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{}
повинні з'являтися окремо, щоб завжди їх розпізнавати, інакше поведінка вільна, щоб символи залишалися незмінними або замінювали їх на ім'я шляху. У першому випадку вся ваша команда фактично видалить усі файли, але останній знайдений ...