Linux удаление множества файлов

Как удалить большое количество файлов в Linux

Удалять файлы можно используя утилиту find, в отличие от ls или rm с указанием маски она не формирует изначально список содержимого каталога, а перебирает файлы по одному.

Посчитать количество файлов можно так

find /home/web/example.com/www/opt/cache/ -type f ¦ wc -l

С -exec rm -f можно запустить процесс удаления файлов (он может занять длительное время)

find /home/web/example.com/www/opt/cache/ -type f -exec rm -f <> \;

Можно попробовать find с опцией delete

find /home/web/example.com/www/opt/cache/ -type f -delete

Скорее всего не даст никакого результата rm с указанием файлов по маске — система при этом до того как начать удаление попытается сформировать полный список файлов, что сделать не получится

Также существует вариант с ls -f, вывод которого перенаправляется в xargs по 100 файлов, затем удаляемых при помощи rm. Может успешно отрабатывать, однако если файлов слишком много вывести список не получится и с ls -f

cd /home/web/example.com/www/opt/cache/ ; ls -f . | xargs -n 100 rm

Самой эффективной командой обычно оказывается find с -exec rm -f, однако все зависит от количества файлов и использовать стоит все представленные варианты (приоритет процессов при удалении имеет смысл максимально понижать используя nice и ionice — алиасы для find или других команд можно добавить в .bashrc пользователя, от имени которого производится удаление).

Источник

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


Феерическая расстановка точек над 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, не увеличивая размер файла образа. Но, с другой стороны, стандартные настройки — ближе к реальным условиям.

Создаем множество пустых файлов (будет работать несколько часов)

Кстати, если в начале файлы создавались достаточно быстро, то последующие добавлялись всё медленнее и медленнее, появлялись рандомные паузы, росло использование памяти ядром. Так что хранение большого числа файлов в плоской директории само по себе плохая идея.

Проверяем, что все айноды на ФС исчерпаны.

Читайте также:  Чем писать диски с windows

Размер файла директории

Теперь попробуем удалить эту директорию со всем её содержимым различными способами.

Тесты

После каждого теста сбрасываем кеш файловой системы
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 вполне возможно?

$ gcc -o cleandir cleandir.c
$ ./cleandir
Под strace один раз вызывает getdents() , потом много раз unlink() и так в цикле. Занял 128Кб памяти, не растет.
Удаляет успешно.

Опять — же, убеждаемся, что использовать readdir — вполне нормально, если не накапливать результаты в памяти, а удалять файлы сразу.

Источник

Быстрое удаление каталога с огромным количеством вложенных файлов и подкаталогов

Столкнулся с проблемой следующего рода:

Имеется каталог, с большим количеством подкаталогов и уровнем вложенности который определить не представляется возможным.
Общий размер каталога около 20Гб, количество файлов более 10 млн. Точное количество файлов определить не хватило терпения (более 3 часов ждал, не долждался), а размер определил методом: вычесть из общего размера занятого на диске размер прочих каталогов, чей размер определить удалось.

Задача: удалить этот каталог со всем его содержимым за минимальный промежуток времени и с минимальным износом ЖД (все это дело на ноутбуке).

пробовал сделать «rm -rfd folder_name», ждал 3 часа, освободило не более 3 Гб и с каждым часом скорость очистки замедлялась.

Может кто другие, более производительные методы подскажет?

перенести все остальное на другой винт, а этот форматнуть и впредь так не делать

подробнее пожалуйста, если можно?

а) +1 за идею забэкапить все кроме этого каталога, снести все нафиг, восстановить все кроме каталога

б) поставить rm -rf на ночь или выходные и не париться, ничего жесткому диску не будет

А по inode-у удалить разве нельзя? Грохни inode каталога и все, прощай файлики. How to: Linux / UNIX Delete or Remove Files With Inode Number

Читайте также:  How to stop nginx mac os

ждал 3 часа, освободило не более 3 Гб

Ну подожди еще сутки. Можно подумать, ты эти три часа педали крутил чтоб оно удалялось.

И дальше по теме 🙂

Ну, или для Ъ — rsync

Стандартное решение: unlink верхней директории, следом umount и fsck.

unlink не работает с каталогами

Дык, я только что сидел, пытался. Оказывается, поломали, сволочи!

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

или ты имел в виду сискол?

Да пофиг. Главное — поломали же такую классную вещь.

потом fsck скажет что ему вусмерть надо поработать и вернет всё в lost+found

Чушь. И да, на reiserfs нет директории lost&found!

А про износ диска ТС-у никто не ответил. Может ему нужно перемонтировать ФС или что написать в /proc, чтобы было усиленное кеширование записи?

Такое вытворял не я, а человек работавший ранее на этом рабочем месте. Сносить все это хозяйство опять же не предоставляется возможным, слишком много инфы + / & /home в одном разделе, так что.

Я не думаю, что разовое удаление такого каталога заметно скажется на износе диска.

А вот если задача становится многократно, я бы посоветовал посмотреть в сторону reisrefs. Мне часто приходится работать с кешами, когда несколько десятков или сотен тысяч файлов на несколько гигабайт или десятков гигабайт лежат в на 2-3 уровнях вложенности в подкаталогах. ext4 на такой структуре через какое-то время использования становится адом. Я несколько лет мучился, пока не рискнул reisrefs проверить, памятуя, что лет 10-15 назад серьёзных проблем с такими структурами (с небольшими поправками на развитие железа) у меня не было. А вправду, одна только синхронизация по rsync на таких объёмах, занимая на ext4 десяток минут, на reiserfs отрабатывает за минуту. Даже (на машинах без lvm, когда легко не переразбить диск) быстрее оказывается в плане скорости поставить reisrefs в файл-образ на ext4.

Источник

Как быстро удалить Очень Много файлов?

Есть раздел под XFS. В нём директория. Выглядит так:

# ls -ldh .
drwxrwxrwx 2 user user 330M Aug 4 01:04

Т.е. только мета-инфа весит 330 Мб (верхняя планка, значит, 1,3-1,4 млн. файлов). Списка имён файлов нет.

Вопрос: как их быстро удалить, с минимальной утилизацией винтов (продакшн-сервер) и без потери остальных данных на этом разделе?

Re: Как быстро удалить Очень Много файлов?

rm -dfr /var/www или че там у тебя

Каждую неделю вопрос на ЛОРе.

Этого вопроса ещё нет в FAQ? (Мне лень смотреть)

find . -maxdepth 1 -type f | xargs -0 ls

Use ionice, Luke!

> Т.е. только мета-инфа весит 330 Мб

Неверно, но к делу отношения не имеет.

> Вопрос: как их быстро удалить,

rm -rf /path/to/dir

> с минимальной утилизацией винтов (продакшн-сервер)

echo cfq > /sys/block/[диск, где находится ФС]/queue/scheduler

ionice -c3 rm -rf /path/to/dir

P.S. Непонятно, чем они так помешали, что понадобилось их так срочно удалять.

Re: Как быстро удалить Очень Много файлов?

Спасибо. С -d всё хорошо.

До этого пробовал:
#find ./ -maxdepth 1 -type f -mtime +7 -exec rm -f <> \;
(не хотелось удалять всё), выглядело так:
——————
#strace -s 360 -p 25670
Process 25670 attached — interrupt to quit
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
getdents64(4, /* 73 entries */, 4096) = 4088
etdents64(4,
Process 25670 detached
——————
, т.е. видимо строило файл-лист и делало это больше недели, с обычным rm было так же (надо было кстати использование памяти замерить).
А с ionice -c3 rm -dfr dir так:
# strace -s 360 -p 933
——————
Process 933 attached — interrupt to quit
unlink(«4e2a0e62921574187660e5ea2155af7e») = 0
unlink(«6094ad144713c973537c162b9e52b5d5») = 0
unlink(«86287687383af5b9c880cd6d4dbaca1c») = 0
unlink(«a8c6a06559e542e396c01a28d6110bbc») = 0
unlink(«ce40f028183e656e1fb5039b8a06dc92») = 0
unlink(«6c66c8ac651afbcd9c3b6dd45a79d506») = 0
unlink(«0753b1f1fcadc9262f0705c897350846») = 0
unlink(«a76ec71296a85087c5e76c413c92e23b») = 0
unlink(«66d65eba60a15d3e44b4058c763dbe74») = 0
— SIGINT (Interrupt) @ 0 (0) —
Process 933 detached
——————

Читайте также:  Драйвер для модема йота для windows 10

Источник

Как удалить все файлы в каталоге, кроме одного

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

Например, вы можете удалить только те, которые начинаются с определенного имени, или те, которые имеют определенное расширение, и так далее. Все что возможноФактически, в других случаях я уже показывал аналогичные уроки в LxA. Здесь вы можете шаг за шагом и простым способом следовать руководству, чтобы удалить все нужные файлы, кроме тех, которые вы хотите сохранить.

И самое лучшее то, что вам не нужно будет устанавливать какую-либо программу, это легко сделать с помощью таких команд, как rm и find. То есть программы, которые уже предустановлены в любом дистрибутиве Linux. И, конечно же, метод будет основан на поиске шаблонов и использовании этих совпадений для удаления только того, что вы хотите.

Ну чтобы там исключить несколько альтернатив, Кто они такие…

Удалить файлы из каталога с помощью rm

Ну, чтобы использовать команда rm Чтобы избавиться от того, что вы чувствуете, вы должны знать перед некоторыми способами выявления закономерностей:

  • * (список шаблонов) — соответствует нулю или более вхождений указанных шаблонов
  • ? (список шаблонов) — соответствует нулю или одному вхождению указанных шаблонов
  • + (список шаблонов) — соответствует одному или нескольким экземплярам указанных шаблонов
  • @ (список шаблонов) — соответствует одному из указанных шаблонов
  • ! (список шаблонов) — соответствует чему угодно, кроме одного из заданных шаблонов

к активировать extglob Чтобы использовать их, вы должны сначала выполнить следующую команду:

глаз! Я не указываю это, но предполагается, что у вас есть разрешения на выполнение этих операций и что вы находитесь внутри этого каталога, когда выполняете команду rm. Будьте осторожны с этим, потому что, если вы запустите его по другому пути, вы можете удалить файлы, которые вам не нужны. То есть перед выполнением этих команд убедитесь, что вы вошли в нужный каталог с помощью cd.

Теперь вы можете использовать rm, чтобы удалить все, что захотите. Например, удалить все файлы из каталога, кроме тех, которые соответствуют имени «Lxa»:

Вы также можете указать два или более имен, которые вы не хотите удалять. Например, чтобы избежать удаления lxa и desdelinux:

Вы можете удалить все файлы, минус те, с расширением .mp3. Например:

В конце вы можете вернуться к отключить extglob:

Удалить файлы из каталога с помощью find

Другая альтернатива rm — используйте find, чтобы удалить то, что вам нравится. Вы можете использовать канал и xargs с rm или использовать параметр -delete для поиска. То есть общий синтаксис будет таким:

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

Вместо этого, если вы хотите добавить дополнительный узор, ты тоже мог бы. Например, предположим, что вы не хотите удалять файлы .pdf или .odt из каталога:

Конечно, вы можете сделать то же самое с | и xargs, как в предыдущем примере. Кстати, мы использовали -не отрицать, но вы можете удалить это, чтобы сделать его положительным, то есть удалить совпадающие шаблоны, а не исключать их.

Удалите файлы из каталога с помощью переменной GLOBIGNORE

Наконец, есть Другая альтернатива чтобы найти и rm, и он использует переменную среды, чтобы указать файлы, которые вы хотите удалить или исключить. Например, представьте, что вы хотите удалить все файлы в каталоге с именем Downloads, сохранив файлы .pdf, .mp3 и .mp4. В этом случае вы можете сделать следующее:

Содержание статьи соответствует нашим принципам редакционная этика. Чтобы сообщить об ошибке, нажмите здесь.

Полный путь к статье: Любители Linux » GNU / Linux » Системное администрирование » Как удалить все файлы в каталоге, кроме одного

Источник

Оцените статью