- Примеры использования программы find с параметром exec
- Параметры программы find
- Действия
- Примеры использования find с параметром exec
- Заключение
- Так как же удалить миллионы файлов из одной папки?
- Подготовка
- Тесты
- Удаление через rm -r
- Удаление через rm ./*
- Удаление через find -exec
- Удаление через find -delete
- Удаление через ls -f и xargs
- Удаление через perl readdir
- Удаление через программу на C readdir + unlink
- Команда find в Linux – мощный инструмент сисадмина
- Поиск по имени
- Поиск по типу файла
- Поиск по размеру файла
- Единицы измерения файлов:
- Поиск пустых файлов и каталогов
- Поиск времени изменения
- Поиск по времени доступа
- Поиск по имени пользователя
- Поиск по набору разрешений
- Операторы
- Действия
- -delete
- Заключение
Примеры использования программы find с параметром exec
В прошлой статье я писал о программе locate, удобной для быстрого поиска файлов в системе.
Альтернативой locate является программа find : GNU find обходит каждый файл из дерева директорий, подставляя его имя в заданное выражение и проводит вычисление значения выражения слева до получения результата (правая часть выражения ложна для операции логического «и», истинна для логического «или»), на основании которого find принимает решение о выполнении заданного действия и переходит к рассмотрению следующего имени файла.
Программа find может принимать различные аргументы командной строки для создания выражения поиска, а стандартным действием при обнаружении файла с именем, удовлетворяющим выражению, является печать имени файла.
Перед тем, как как привести полезные примеры использования программы find с параметром exec , рассмотрим немного теоретических положений.
Параметры программы find
Наиболее известными параметрами для поиска файлов при помощи программы find , являются:
-name выражение Это наиболее часто используемый параметр для поиска файлов, имена которых (без учета предшествующих им директорий) удовлетворяют заданному выражению.
-mtime n Файлы были изменены n*24 часов назад.
-uid n Системный числовой идентификатор пользователя-владельца файла должен быть равен n .
Действия
При использовании find есть возможность для указания действий, которые будут выполнены при нахождении файла с именем, удовлетворяющим выражению поиска, а наиболее гибким вариантом, без сомнения, является использование параметра exec .
-exec команда; Выполнить команду; выполнение считается успешным в случае статуса выхода, равного нулю. Все символы, следующие за командой, считаются ее аргументами до того момента, как встречается символ «;» . Строка «<>» заменяется на имя рассматриваемого файла каждый раз, когда она встречается среди аргументов команды.
Примеры использования find с параметром exec
Поиск файлов и удаление их при помощи параметра exec является часто встречающимся вариантом использования этого параметра, но вам не нужно использовать exec для этих целей, так как более удачный вариант будет описан позднее.
В старых системах Unix у вас не будет возможности использовать параметр -delete , поэтому альтернатив параметру -exec для удаления файлов в них не остается.
А теперь рассмотрим некоторые другие примеры использования программы find с параметром exec .
При помощи параметра -type f вы можете вести поиск только файлов и просто изменять права доступа к каждому из них при помощи chmod .
В этом примере я использовал параметр -user как альтернативу параметру -uid .
В этом примере я снова использовал параметр -type , но на этот раз с аргументом d для поиска директорий.
Заключение
Как вы убедились, в приведенных выше примерах показано то, что использование программы find с параметром exec позволяет вам выполнять довольно сложные задачи, при этом то обстоятельство, что вы можете выполнять заданное действие только над частью файлов, ставит вас в выигрышное положение.
Источник
Так как же удалить миллионы файлов из одной папки?
Феерическая расстановка точек над i в вопросе удаления файлов из переполненной директории.
Прочитал статью Необычное переполнение жесткого диска или как удалить миллионы файлов из одной папки и очень удивился. Неужели в стандартном инструментарии Linux нет простых средств для работы с переполненными директориями и необходимо прибегать к столь низкоуровневым способам, как вызов getdents() напрямую.
Для тех, кто не в курсе проблемы, краткое описание: если вы случайно создали в одной директории огромное количество файлов без иерархии — т.е. от 5 млн файлов, лежащих в одной единственной плоской директории, то быстро удалить их не получится. Кроме того, не все утилиты в linux могут это сделать в принципе — либо будут сильно нагружать процессор/HDD, либо займут очень много памяти.
Так что я выделил время, организовал тестовый полигон и попробовал различные средства, как предложенные в комментариях, так и найденные в различных статьях и свои собственные.
Подготовка
Так как создавать переполненную директорию на своём HDD рабочего компьютера, потом мучиться с её удалением ну никак не хочется, создадим виртуальную ФС в отдельном файле и примонтируем её через loop-устройство. К счастью, в Linux с этим всё просто.
Создаём пустой файл размером 200Гб
Многие советуют использовать для этого утилиту dd, например dd if=/dev/zero of=disk-image bs=1M count=1M , но это работает несравнимо медленнее, а результат, как я понимаю, одинаковый.
Форматируем файл в ext4 и монтируем его как файловую систему
К сожалению, я узнал об опции -N команды mkfs.ext4 уже после экспериментов. Она позволяет увеличить лимит на количество inode на FS, не увеличивая размер файла образа. Но, с другой стороны, стандартные настройки — ближе к реальным условиям.
Создаем множество пустых файлов (будет работать несколько часов)
Кстати, если в начале файлы создавались достаточно быстро, то последующие добавлялись всё медленнее и медленнее, появлялись рандомные паузы, росло использование памяти ядром. Так что хранение большого числа файлов в плоской директории само по себе плохая идея.
Проверяем, что все айноды на ФС исчерпаны.
Размер файла директории
Теперь попробуем удалить эту директорию со всем её содержимым различными способами.
Тесты
После каждого теста сбрасываем кеш файловой системы
sudo sh -c ‘sync && echo 1 > /proc/sys/vm/drop_caches’
для того чтобы не занять быстро всю память и сравнивать скорость удаления в одинаковых условиях.
Удаление через rm -r
$ rm -r /mnt/test_dir/
Под strace несколько раз подряд (. ) вызывает getdents() , затем очень много вызывает unlinkat() и так в цикле. Занял 30Мб RAM, не растет.
Удаляет содержимое успешно.
Т.е. удалять переполненные директории с помощью rm -r /путь/до/директории вполне нормально.
Удаление через rm ./*
$ rm /mnt/test_dir/*
Запускает дочерний процесс шелла, который дорос до 600Мб, прибил по ^C . Ничего не удалил.
Очевидно, что glob по звёздочке обрабатывается самим шеллом, накапливается в памяти и передается команде rm после того как считается директория целиком.
Удаление через find -exec
$ find /mnt/test_dir/ -type f -exec rm -v <> \;
Под strace вызывает только getdents() . процесс find вырос до 600Мб, прибил по ^C . Ничего не удалил.
find действует так же, как и * в шелле — сперва строит полный список в памяти.
Удаление через find -delete
$ find /mnt/test_dir/ -type f -delete
Вырос до 600Мб, прибил по ^C . Ничего не удалил.
Аналогично предыдущей команде. И это крайне удивительно! На эту команду я возлагал надежду изначально.
Удаление через ls -f и xargs
$ cd /mnt/test_dir/ ; ls -f . | xargs -n 100 rm
параметр -f говорит, что не нужно сортировать список файлов.
Создает такую иерархию процессов:
ls -f в данной ситуации ведет себя адекватнее, чем find и не накапливает список файлов в памяти без необходимости. ls без параметров (как и find ) — считывает список файлов в память целиком. Очевидно, для сортировки. Но этот способ плох тем, что постоянно вызывает rm , чем создается дополнительный оверхед.
Из этого вытекает ещё один способ — можно вывод ls -f перенаправить в файл и затем удалить содержимое директории по этому списку.
Удаление через perl readdir
$ perl -e ‘chdir «/mnt/test_dir/» or die; opendir D, «.»; while ($n = readdir D) < unlink $n >‘ (взял здесь)
Под strace один раз вызывает getdents() , потом много раз unlink() и так в цикле. Занял 380Кб памяти, не растет.
Удаляет успешно.
Получается, что использование readdir вполне возможно?
Удаление через программу на C readdir + unlink
$ gcc -o cleandir cleandir.c
$ ./cleandir
Под strace один раз вызывает getdents() , потом много раз unlink() и так в цикле. Занял 128Кб памяти, не растет.
Удаляет успешно.
Опять — же, убеждаемся, что использовать readdir — вполне нормально, если не накапливать результаты в памяти, а удалять файлы сразу.
Источник
Команда find в Linux – мощный инструмент сисадмина
Иногда критически важно быстро найти нужный файл или информацию в системе. Порой можно ограничиться стандартами функциями поиска, которыми сейчас обладает любой файловый менеджер, но с возможностями терминала им не сравниться.
Команда find – это невероятно мощный инструмент, позволяющий искать файлы не только по названию, но и по:
- Дате добавления.
- Содержимому.
- Регулярным выражениям.
Данная команда будет очень полезна системным администраторам для:
- Управления дисковым пространством.
- Бэкапа.
- Различных операций с файлами.
Команда find в Linux производит поиск файлов и папок на основе заданных вами критериев и позволяет выполнять действия с результатами поиска.
Синтаксис команды find:
- directory-to-search (каталог поиска) – это отправной каталог, с которой find начинает поиск файлов по всем подкаталогам, которые находятся внутри. Если не указать путь, тогда поиск начнется в текущем каталоге;
- criteria (критерий) – критерий, по которым нужно искать файлы;
- action (действие) – что делать с каждым найденным файлом, соответствующим критериям.
Поиск по имени
Следующая команда ищет файл s.txt в текущем каталоге:
- . (точка) – файл относится к нынешнему каталогу
- -name – критерии по которым осуществляется поиск. В данном случае поиск по названию файла.
В данном случае критерий -name учитывает только символы нижнего регистра и файл S.txt не появиться в результатах поиска. Чтобы убрать чувствительность к регистру необходимо использовать –iname.
Для поиска всех изображений c расширением .png нужно использовать шаблон подстановки *.png:
Можно использовать название каталога для поиска. Например, чтобы с помощью команды find найти все png изображения в каталоге home:
Если выдает слишком много ошибок в отказе разрешения, тогда можно добавить в конец команды – 2> /dev/null. Таким образом сообщения об ошибках будут перенаправляться по пути dev/null, что обеспечит более чистую выдачу.
Поиск по типу файла
Критерий -type позволяет искать файлы по типу, которые бывают следующих видов:
- f – простые файлы;
- d – каталоги;
- l – символические ссылки;
- b – блочные устройства (dev);
- c – символьные устройства (dev);
- p – именованные каналы;
- s – сокеты;
Например, указав критерий -type d будут перечислены только каталоги:
Поиск по размеру файла
Допустим, что вам необходимо найти все большие файлы. Для таких ситуаций подойдет критерий -size.
- «+» — Поиск файлов больше заданного размера
- «-» — Поиск файлов меньше заданного размера
- Отсутствие знака означает, что размер файлов в поиске должен полностью совпадать.
В данном случае поиск выведет все файлы более 1 Гб (+1G).
Единицы измерения файлов:
Поиск пустых файлов и каталогов
Критерий -empty позволяет найти пустые файлы и каталоги.
Поиск времени изменения
Критерий -cmin позволяет искать файлы и каталоги по времени изменения. Для поиска всех файлов, измененных за последний час (менее 60 мин), нужно использовать -60:
Таким образом можно найти все файлы в текущем каталоге, которые были созданы или изменены в течение часа (менее 60 минут).
Для поиска файлов, которые наоборот были изменены в любое время кроме последнего часа необходимо использовать +60.
Поиск по времени доступа
Критерий -atime позволяет искать файлы по времени последнего доступа.
Таким образом можно найти файлы, к которым не обращались последние полгода (180 дней).
Поиск по имени пользователя
Опция –user username дает возможность поиска всех файлов и каталогов, принадлежащих конкретному пользователю:
Таким образом можно найти все файлы пользователя tisha в каталоге home, а 2>/dev/null сделает выдачу чистой без ошибок в отказе доступа.
Поиск по набору разрешений
Критерий -perm – ищет файлы по определенному набору разрешений.
Поиск файлов с разрешениями 777.
Операторы
Для объединения нескольких критериев в одну команду поиска можно применять операторы:
Например, чтобы найти файлы размером более 1 Гбайта пользователя tisha необходимо ввести следующую команду:
Если файлы могут принадлежать не только пользователю tisha, но и пользователю pokeristo, а также быть размером более 1 Гбайта.
Перед скобками нужно поставить обратный слеш «\».
Действия
К команде find можно добавить действия, которые будут произведены с результатами поиска.
- -delete — Удаляет соответствующие результатам поиска файлы
- -ls — Вывод более подробных результатов поиска с:
- Размерами файлов.
- Количеством inode.
- -print Стоит по умолчанию, если не указать другое действие. Показывает полный путь к найденным файлам.
- -exec Выполняет указанную команду в каждой строке результатов поиска.
-delete
Полезен, когда необходимо найти и удалить все пустые файлы, например:
Перед удалением лучше лишний раз себя подстраховать. Для этого можно запустить команду с действием по умолчанию -print.
Данное действие является особенным и позволяет выполнить команду по вашему усмотрению в результатах поиска.
- command – это команда, которую вы желаете выполнить для результатов поиска. Например:
- rm
- mv
- cp
- <> – является результатами поиска.
- \; — Команда заканчивается точкой с запятой после обратного слеша.
С помощью –exec можно написать альтернативу команде –delete и применить ее к результатам поиска:
Другой пример использования действия -exec:
Таким образом можно скопировать все .jpg изображения в каталог backups/fotos
Заключение
Команду find можно использовать для поиска:
- Файлов по имени.
- Дате последнего доступа.
- Дате последнего изменения.
- Имени пользователя (владельца файла).
- Имени группы.
- Размеру.
- Разрешению.
- Другим критериям.
С полученными результатами можно сразу выполнять различные действия, такие как:
- Удаление.
- Копирование.
- Перемещение в другой каталог.
Команда find может сильно облегчить жизнь системному администратору, а лучший способ овладеть ей – больше практиковаться.
Источник