Как мне освоить команду поиска UNIX?


11

Я думаю, что я довольно продвинут в использовании 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 не будет пересекать разделы, но я не уверен, что случится с файлами, находящимися внутри каталогов, которые являются символическими ссылками.

Так как же овладеть этим зверем, который может убивать важные файлы?

Обновление обрезки лучших предложений ниже и подведение итогов:

  1. Имейте каталог практики, связанный и смонтированный с другими каталогами практики.
  2. Используйте xargs вместо неинтуитивной команды exec.
  3. Используйте -exec echo {} для здравомыслия и безопасности
  4. Точка с запятой особенная, и вы избегаете ее, поэтому первым должен быть экранирующий символ
  5. Команда -or может помочь вам объединить критерии выбора.

Я немного растерялся из-за print0, но xargs всегда был немного непростым на первый взгляд практикой, которой я стараюсь избегать.


1
Я тоже не могу вспомнить, поэтому я просто отправляю это в xargs.
резонатор

2
Если вы удовлетворены созданием правильной команды, попробуйте запустить ее с + вместо \; Он будет работать быстрее с +, потому что команда exec будет вызываться намного реже.
wzzrd

wzzrd, отличный совет по использованию + вместо \;
Даниэль Лоусон

Ответы:


19

Ну, что касается -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 {} \;

и просмотрите результаты. Это в основном «пробный запуск», когда вы видите команды, которые он будет запускать, если вы позволите. Определенно хорошая практика. Не поможет с .*проблемой, но вы знаете, не делать это сейчас. :)


1
+! для "эха" тренируйтесь на пробежке. Я всегда использую это для больших перемен
Стив Фолли

3

Я удивлен, что никто еще не упомянул следующую опцию:

find . -type f -ok chown username {} \;

Этот синтаксис подтвердит команду перед ее выполнением. Это работает лучше всего, если вы ожидаете, что ваше совпадение будет относительно небольшим количеством файлов, поскольку оно будет запрашивать каждый из них.

В некоторых ответах упоминается xargs, но с GNU это тоже не нужно:

find . -type f -exec chown username {} \+

Обратите внимание, что + обычно не нужно экранировать, но в любом случае полезно привыкнуть к этому.


Можете ли вы объяснить природу знака плюс ... что именно он делает? Обрабатывает ли его оболочка или команду. Я думаю, что я собираюсь скачать исходный код для gnu-find, потому что это интересная тема.
ojblass

находка обрабатывает это. Читайте man find, чтобы узнать больше об этом варианте.
Камил Кисиэль

3

Это то, для чего нужен человек: бывает сложно запомнить что-то, поэтому команда * nix включает в себя страницы руководства. Вы можете просто всегда проверяйте раздел ACTION страницы человека для напоминания о синтаксисе: man find. Хотя справочные страницы могут показаться не очень дружелюбными, но когда вы научитесь читать их, они очень пригодятся.

Создайте интерфейс или оболочку. Когда я захотел стать лучше в GNU find, я написал графический интерфейс GUI для find, который генерирует команды find с python, glade и pygtk. Это хорошее упражнение, если вы хотите узнать его очень хорошо.

Есть каталог практики: Наконец, у меня всегда есть каталог «записки» в моей домашней директории для игры с мощными командами, когда что-то вроде «эхо» не обрезает его. Вы можете использовать расширение оболочки, чтобы быстро создать кучу файлов с чем-то вроде:

for i in {1..100}; do touch "$i"; done

Странный каталог практики - это то, что я никогда не рассматривал.
ojblass

1

Вы также можете комбинировать выражения find с операторами «-and» и «-or». -и неявно:

find . -type f -name "plainfile" ...

такой же как

find . -type f -and -name "plainfile" ...

Оператор или может сократить ваш список из 4 команд до 2:

find . -type d -or -type f ...

И, наконец, не имеет отношения к поиску, но Чоун также может установить группу. Итак, справляясь с пробелами в именах, мы получаем:

find . -type d -or -type f -exec chown username:usergroup '{}' \;

Что найти с-или бизнесом. [Sic]
ojblass

@ojblass: find объединяет выражения с использованием «и» или «или», по умолчанию, если не указаны ни «-and», ни «-or», «-and» используется неявно. Поэтому тип 'find -type d -type f' ничего не найдет, потому что ничто не является каталогом и файлом.
Стив Фолли

0

При закрытии я просто думаю об использовании; как со многими языками программирования, а затем избежать его. Просто помните, что от него нужно сбежать, и оно приходит к вам довольно легко.


0

В зависимости от версии find, которую вы используете, могут быть разные варианты. GNU find является, вероятно, самым мощным, и это может помочь вам с вашим вторым (подразумеваемым) вопросом

Например, поведение по умолчанию - не разыменовывать символические ссылки, но вы можете переопределить это; и опция -mount останавливает поиск переходов через точки монтирования

Посмотрите на местных страницах руководства


0

Некоторые утверждают, что параметр xargs работает быстрее, чем параметр -exec, потому что он не будет выполнять команду один раз для каждого файла, но я не стал бы беспокоиться об этом ни за чем, кроме массовых заданий, занимающих нетривиальное количество времени.

Лично я обычно просто запускаю поиск без exec

find /path/to/dir -name whatever

убедитесь, что вывод выглядит правильно, а затем запустите мою команду в этом списке.

chown user:group `find /path/to/dir -name whatever`

Прекрасный пример того, как «не» делать вещи. Имена файлов с пробелами.
Ян Келлинг

Да, это потенциальная проблема, которую я, возможно, должен был признать. Тем не менее, моя цель была о том, чтобы прочитать результаты поиска перед выполнением чего-либо, где вы заметили пробелы или другое безумие имени файла.
другой прием

0

Для некоторых оболочек (не bash) используйте {} для правильного поведения.

\{\} or '{}'

найти руководство хорошо для освоения найти.


Нет, ты не; find отлично работает с {} как есть. Они являются частью команды find: они являются токеном, который заменяется результатом команды find. Они только что-то означают в bash при определении функций или вызове переменных, поэтому вы можете просто использовать их, как в исходном вопросе.
wzzrd

Это из справочной страницы. Я обновил, чтобы сказать, что это не относится к Bash.
Ян Келлинг

0

Прежде чем делать что-либо подобное, убедитесь, что каталог, в котором вы запускаете эту команду, не находится в той же файловой системе, что и / usr или / etc. (в противном случае, если у меня есть жесткая ссылка на / etc / passwd или на / bin / sh в моем домашнем каталоге, вы только что дали мне право собственности на них, и в качестве побочного эффекта я теперь владею машиной).

Если вы хотите пройти через каталог и разбить все файлы / каталоги, просто

chown -Rh пользователь: пользователь группы /

сделаю это. Убедитесь, что вы используете -h, или chown будет следовать по символическим ссылкам.


Я не думаю, что это кроссплатформенный. Также происходит сбой с 247K файлов, как продемонстрировано моей практикой. Я не уверен почему.
ojblass

Я думаю, вы нашли ошибку больше, чем проблему кроссплатформенности. Какая версия и каков статус выхода при сбое? Насколько я могу судить, он впервые появился в ранних версиях BSD; Это определенно в Sunos 5.3 и Ultrix и Irix. Сколько он обрабатывает, прежде чем терпит неудачу?
Крис

Вы правы, он работает на AIX 5.3, AIX 5.2, но не на AIX 4.3, NCR, HP 11, HP 10.20 или моих дистрибутивах DSL. Во всех случаях это, кажется, терпит неудачу в или около 60k файлов.
ojblass
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.