Я думаю, что я достаточно продвинутый в использовании find, но КАЖДЫЙ раз, когда я его использую, я не могу на всю жизнь вспоминать метод закрытия опции -exec. Я провожу много времени за чтением каждый раз, когда использую его. Я просто недостаточно им пользуюсь или слишком многого жду от себя? Начнем с типичного примера, который меня расстраивает.
В структуре каталогов есть файлы со всеми неправильными разрешениями, скрытые файлы, символические ссылки и т. Д. Я хочу изменить право собственности на разумное значение
find . -type f -exec chown username {} \;
find . -type d -exec chown username {} \;
find . -type d -exec chgrp usergroup {} \;
find . -type f -exec chgrp usergroup {} \;
(Простите, если финал обратный ... Я смотрел его час назад и все еще не уверен)
Но я боюсь запускать его из-за монтировок, символических ссылок и т. Д. Я сделал окончательный трюк с chmod. *, И раньше он возвращался вверх на меня. Я знаю, что -xdev не будет пересекать разделы, но я не уверен, что произойдет с файлами, находящимися внутри каталогов, которые являются символическими ссылками.
Так как же справиться с этим чудовищем, способным уничтожать важные файлы?
Обновить отсекая лучшие предложения ниже и резюмируя:
Я немного запутался в print0, но xargs всегда был немного непростым для понимания на первый взгляд практикой, которую я стараюсь избегать.
Ну а что касается -exec
синтаксис идет, вы могли бы поступить так, как многие люди, сдаться и использовать xargs
:
find . -type f | xargs chown username
(или безопасная версия с файлами с пробелами и прочей ерундой)
find . -type f -print0 | xargs -0 chown username
Или, чтобы попытаться вспомнить, как правильно использовать точку с запятой, вам нужно вбить в голову, что вы используете точку с запятой для прекратить команда, которая -exec
работает, и вы должны побег точка с запятой, потому что она имеет особое значение для bash
. Вот почему это обратная косая черта, точка с запятой. Кажется, у тебя есть {}
замена части в порядке.
Что касается уничтожения файлов и так далее, если вы запускаете что-то большое и опасное, о чем говорите, сначала сделайте следующее:
find . -type f -exec echo chown username {} \;
и просмотрите результаты. По сути, это «пробный запуск», когда вы видите команды, которые он запустил бы, если бы вы ему позволили. Определенно хорошая практика. Не поможет с .*
проблема, но вы знаете, что сейчас не стоит этого делать. :)
Вот для чего нужен мужчина: Может быть трудно что-то запомнить, поэтому команда * nix включает справочные страницы. Вы всегда можете просто проверить раздел ACTION на странице руководства, чтобы узнать о синтаксисе: man find
. Хотя страницы руководства могут показаться не слишком дружелюбными, как только вы научитесь их читать, они станут очень удобными.
Сделайте Front-End или Wrapper: Когда я хотел стать лучше в GNU find, я написал Интерфейс GUI для поиска который генерирует команды поиска с помощью python, glade и pygtk. Это хорошее упражнение, если вы хотите узнать его по-настоящему.
Иметь справочник по практике: Наконец, у меня всегда есть каталог scrap в моем домашнем каталоге для игры с мощными командами, когда что-то вроде «echo» его не режет. Вы можете использовать расширение оболочки, чтобы быстро создать кучу файлов, например:
for i in {1..100}; do touch "$i"; done
Я удивлен, что никто еще не упомянул следующий вариант:
find . -type f -ok chown username {} \;
Этот синтаксис подтвердит команду перед ее выполнением. Лучше всего работает, если вы ожидаете, что вашим совпадением будет относительно небольшое количество файлов, потому что он будет запрашивать каждый из них.
В некоторых ответах упоминается xargs
, но с GNU это тоже не нужно:
find . -type f -exec chown username {} \+
Обратите внимание, что + обычно не нужно экранировать, но все равно хорошо привыкнуть к этому.
Вы также можете комбинировать выражения поиска с операторами «-and» и «-or». -и неявно:
find . -type f -name "plainfile" ...
такой же как
find . -type f -and -name "plainfile" ...
Оператор or может уменьшить ваш список из 4 команд до 2:
find . -type d -or -type f ...
И, наконец, не относящийся к find, но chown также может установить группу. Итак, справляясь с пробелами в именах, мы получаем:
find . -type d -or -type f -exec chown username:usergroup '{}' \;
При закрытии я просто думаю об использовании; как и во многих языках программирования, а затем избежать этого. Просто помните, что от него нужно сбежать, и это довольно легко придет к вам.
В зависимости от версии find, которую вы используете, вам могут помочь разные варианты. GNU find, вероятно, самый мощный, и это может помочь вам со вторым (подразумеваемым) вопросом
Например, по умолчанию символические ссылки не разыменовываются, но вы можете это переопределить; и опция -mount останавливает поиск точек монтирования
Посмотрите на свои локальные страницы руководства
Некоторые будут спорить что параметр xargs быстрее, чем параметр -exec, потому что он не выполняет команду один раз для каждого файла, но я бы не стал беспокоиться об этом ни для чего, кроме массивных заданий, занимающих нетривиальное количество времени.
Лично я обычно просто запускаю find без exec
find /path/to/dir -name whatever
убедитесь, что вывод выглядит правильно, а затем запустите мою команду в этом списке.
chown user:group `find /path/to/dir -name whatever`
Для некоторых оболочек (не bash) escape {} для правильного поведения.
\{\} or '{}'
Инструкция по поиску хороша для освоения находки.
Прежде чем делать что-либо подобное, убедитесь, что каталог, в котором вы запускаете эту команду, не находится в той же файловой системе, что и / usr или / etc. (в противном случае, если у меня есть жесткая ссылка на / etc / passwd или на / bin / sh в моем домашнем каталоге, вы только что предоставили мне право собственности на них, и в качестве побочного эффекта теперь я владею машиной).
Если вы хотите пройти через каталог и перебрать все файлы / каталоги, простой
chown -Rh пользователь: пользователь группы пользователей /
сделаю это. Делать конечно вы используете -h или chown будет переходить по символическим ссылкам.