Cmd удалить файлы больше
Скорей всего, матерым системным администраторам статья будет не очень интересна. В первую очередь она ориентирована на новичков, а также на людей, которые столкнулись с подобной проблемой — необходимостью удалить огромное количество файлов из одной папки в ОС Linux (Debian в моем случае), а также с закончившимся местом на диске, когда df -h выдает что почти 30% свободно.
Начало
Ничто не предвещало беды.
Сервер с сайтом работал без никаких проблем уже больше года (uptime почти 500 дней), не было никаких проблем, и я с чистой душой спокойно ушел в отпуск.
В первый же день отпуска мне звонят с жалобой — сайт недоступен. MySQL падает с ошибкой Error 28 «No space left on device».
Казалось бы, проблема банальна — кончилось место на диске. Правда, df -h показывает, что на диске имеется вполне достаточное количество свободного места, ну да я же в отпуске, разбираться лень — посоветовал им поискать на диске ненужные файлы (старые бекапы и т.д.) и их удалить. Удалили, вроде все заработало.
Прошла пара часов и проблема вернулась. Странно — свободное место на жестком диске за это время практически не уменьшилось. После беглого гугления обнаружился топик на serverfault, в котором говорится, что проблема может возникнуть также из-за того, что кончилось не место на диске, а айноды!
Ввожу в консоль df -i — и оказывается действительно, айноды у меня закончились.
Проблема
Начал искать, где же у меня находится столько файлов на жестком диске, что они сожрали все айноды (а айнодов у меня на 500-гигабайтном жестком диске больше 30 миллионов).
И нашел — оказалось, проблема была в папке с сессиями php.
Видимо, по какой-то причине сломался механизм автоочистки этой папки, что привело к тому, что в ней скопилось огромное количество файлов. Насколько огромное — сказать сложно, потому что никакие стандартные команды линукс, такие, как ls, find, rm и т.д. — с этой папкой не работают. Просто виснут, заодно подвешивая весь сервер. Могу только сказать, что сам файл директории стал весит около гигабайта, а также что файлов там точно более полумиллиона, потому что столько я оттуда уже удалил.
Решение
Решение очевидное — надо удалить все эти файлы сессий. При этом желательно, чтобы сервер продолжал работать в штатном режиме. Для начала я переименовал папку сессий, в которой лежит куча файлов, а вместо нее создал пустую — чтобы спокойно из старой (переименованной) удалять все файлы, и чтобы это не мешало созданию новых файлов сессий.
Также в крон добавил автоматическое удаление файлов сессий старше одного часа, чтобы проблема больше не повторилась.
И перешел к основной проблеме — очистке жесткого диска.
Попробовал решение «в лоб»:
Сервер повис, ничего не удалилось
Попробовал известный способ для удаления большого числа файлов
Ничего, сервер виснет, файлы не удаляются.
А теперь что самое интересное — файловый менеджер mc достаточно успешно справлялся с задачей удаления этих файлов! То есть, когда запускаешь удаление папки — файлы удаляются, mc не виснет. Удаление идет со скоростью примерно 5 000 файлов в минуту, правда при этом создается огромная нагрузка на жесткий диск, что приводит к неработоспособности сервера.
А хотелось бы, чтобы эти файлы постепенно удалялись в фоновом режиме, и не мешали нормальной работе сайта.
Собственно, решение опять нашлось в гугле — Olark делится способом, как он отобразил список из 8 миллионов файлов в 1 папке, используя системный вызов getdents
Здесь находится документация по функции getdents, а также пример кода, который ее использует.
Правда, этот пример мне не совсем подошел — даже если ставить большой размер буфера, как советует Olark в своем блоге, все равно сервер виснет при попытке прочитать всю папку разом.
Опытным путем подобрал размер буфера в 30 килобайт, который позволяет считать около 550 названий файлов из директории, при этом не подвешивая сервер и не создавая излишней нагрузки на диск. А также немного переписал код примера, чтобы вместо отображения имени файла он его удалял.
В итоге у меня получился такой код:
Код компиллируется обычным gcc
И просто запускается из командной строки:
Получившийся файл я поставил в крон и теперь у меня удаляется по 547 файлов в минуту, при этом нагрузка на сервер в пределах нормы — и я надеюсь, в течение недели-другой все файлы все-таки удалятся.
Доброго времени суток. Помогите написать батник, который бы подсчитывал общий размер всех файлов в папке и при превышении 10 ГБ удалял бы самые старые из них, пока снова не будет менее 10 ГБ.
Работа с файловой системой. Поиск файлов, удаление файл размер которого превышает 100 килобайт
Всем привет! Помогите пожалуйста! Вообщем необходимо реализовать программу , которая будет.
Вывести 10 самых старых сотрудников и 10 самых высокоплачиваемых
Здравствуйте, подскажите пожалуйста, у меня есть БД где написаны сотрудники предприятия с.
Удаление старых файлов
Set objShell = WScript.CreateObject("WScript.Shell") Set fso =.
V1RTuE,
может конечно такого и не будет, но почему бы и нет, посему считаю затею (подход) бредовой.
Вар1
file 08.09.2017 8Gb - удалится только этот
file 09.09.2017 4Gb
file 10.09.2017 3Gb
file 11.09.2017 2Gb
file 12.09.2017 1Gb
Куча остальных, подходящих "по старости", лежит
Вар2
file 08.09.2017 1Gb
file 09.09.2017 2Gb
file 10.09.2017 3Gb
file 11.09.2017 9Gb - удалять только этот? Дальше условию удовлетворяет
file 12.09.2017 1Gb
V1RTuE,
твои мотивы, определяющие постановку такой задачи, неизвестны,
но подумай над альтернативной стратегией: 'Просто установить квоту в 10Гб на данный каталог' *
( * ) не уверен, что это (квоты на каталоги и подкаталоги) возможно для клиентских версий Windows, но для серверных - да.
В общем суть такова. Есть папка, синхронизируемая с облачным хранилищем. Регулярно в эту папку копируются файлы от 100 до 500 мб. Папка конечно вместит и больше 10гб, но синхронизация с облаком тогда происходить не будет. Самые старые файлы уже будут не нужны. Можно конечно и сделать удаление файлов старше х дней, но количество файлов может меняться как и их размер. Хотелось бы в облаке на всякий случай иметь бэкап на максимально возможное количество дней. Ежедневно копируются одни и те же файлы (в архивах с разным именем - датой), но обновлённые.
Добавлено через 1 минуту
alpap, вариант 1 как раз подходит. Вариант 2 нет. Не важен размер, главное дата.
это не руководство к действию было - это проблема.
Удаление старых файлов
Создать программу удалял файлы старше N дней в определённой папке. 1 Надо все данные ввести из.
Удаление старых файлов
Добрый день. Есть база для работы пользователей. Решил сделать exe'шник на запуск. И чтобы проверял.
Удаление старых файлов
Доброго времени суток ув. форумчане! Говорю сразу в шеле я профан полный!:( В общем поставили.
Удаление старых файлов из подпапок
Доброго времени суток всем. Есть каталог /dir/, в нём множество подкаталогов с файлами.
Удаляет один или несколько файлов. Эта команда выполняет те же действия, что и команда Erase .
команда del также может запускаться из консоли восстановления Windows с использованием различных параметров. дополнительные сведения см. в разделе Windows среды восстановления (WinRE).
Если удалить файл с диска с помощью Del , вы не сможете получить его.
Синтаксис
Параметры
- файлы r только для чтения
- h скрытые файлы
- я не проиндексированные файлы содержимого
- системные файлы
- файлы , готовые к архивации
- l точки повторного анализа
- - Используется в качестве префикса, означающего "not"
Комментарии
FileName, Delete (Y/N)?
Чтобы подтвердить удаление, нажмите клавишу Y. Чтобы отменить удаление и отобразить следующее имя файла (если указана группа файлов), нажмите клавишу N. Чтобы закрыть команду Del , нажмите клавиши CTRL + C.
Если вы отключаете расширение команды, параметр /s отображает имена всех файлов, которые не были найдены, а не отображает имена удаляемых файлов.
Если указать определенные папки в параметре, все включаемые файлы также будут удалены. Например, если нужно удалить все файлы в папке \ворк , введите:
Можно использовать подстановочные знаки ( * и ?) для удаления нескольких файлов за раз. Однако во избежание непреднамеренного удаления файлов следует использовать подстановочные знаки с осторожностью. Например, если ввести следующую команду:
Are you sure (Y/N)?
Чтобы удалить все файлы в текущем каталоге, нажмите клавишу Y и нажмите клавишу ВВОД. Чтобы отменить удаление, нажмите клавишу N и нажмите клавишу ВВОД.
Прежде чем использовать подстановочные знаки с командой Del , используйте те же подстановочные знаки с командой dir , чтобы получить список всех файлов, которые будут удалены.
Примеры
Чтобы удалить все файлы в папке с именем Test на диске C, введите следующую команду:
Чтобы удалить все файлы с расширением имени файла .bat из текущего каталога, введите:
создание сайтов, заработок в сети, раскрутка, программирование
В Украине война. Путинские войска нас бомбят.
Делаю бекапы каждый день, накапливается не один десяток гигабайт информации. Чистить нужно, тем более старые бекапчики особой важности не несут. Раньше удалял вручную, но потом задумался… Вручную делать это лень, тем более можешь завтыкать, протупить и удалить не то. Короче, ленивый сделает лучше всех — нужно автоматизировать.
Воспользовался встроенной утилитой forfiles. Теперь все делает планировщик задач и несложный bat-ник в две строки. Пример дальше.
Команды forfiles. Примеры
Вот так примерно выглядит команда для отображения всех файлов с расширением .rar на диске С старше 10-ти дней:
forfiles /p C:\ /m *.rar /s /d -10 /c «cmd /c echo @path»
Разберем ключи по порядку:
/p — пусть для проверки. В примере диск C:\
/m — маска для поиска. Можно не задавать, если хотим убрать все файлы в папке. В примере все архивы с расширением .rar
/s — сканируем вложенные папки в том числе.
/d — дата. Можно задать в формате dd.mm.yyyy или dd. У нас -10 дней, можно указать +N дней. Про +N дней читайте далее.
/c — команда. Ключевое что нам нужно — собственно что мы будем делать с файлами. В командах также можно использовать переменные:
@path — показывает полный путь к файлу и его имя.
@relpath — показывает путь к файлу только в сканируемой папке.
@file — имя файла полностью с расширением.
@fname — только имя файла, без расширения.
@ext — только расширение имени файла.
@isdir — проверка типа файла — папка или файл. Возвращает true, если папка, и false для файлов.
@fsize — возвращает размер файла в байтах.
@fdate — возвращает дату последнего изменения файла.
@ftime — возвращает время последнего изменения файла.
Также результаты исполнения скрипта можно записать в файл.
Пример использования forfiles — отобразить все файлы .zip на диске и записать их в файл
Следующий код отобразит все Ваши исполняемые файлы .exe:
forfiles /p C:\ /m *.exe /s /c «cmd /c echo @path»
Если нужно их записать в файл, то добавьте в конце знак БОЛЬШЕ и адрес куда сохранить файл (лучше всего прописать полный путь).
forfiles /p C:\ /m *.exe /s /c «cmd /c echo @path» > D:\all_exefiles.txt
Вставляем код в cmd:
Результат — созданный файл на диске D:\ и его содержимое (можно много интересного найти):
Пример forfiles с переменными путь, дата, размер
Давайте вызовем все наши файлы с диска D:\ с расширением .zip, а выведем их на экран с адресом, датой и размером файла. Используем скрипт:
forfiles /p D:\ /m *.zip /s /c «cmd /c echo @path изменен @fdate и размером @fsize байт »
Вот результат выполнения скрипта:
Как удалить файлы старше 10 дней
Чаще всего forfiles используют как раз для задачи удаления устаревших файлов. Вот Вам cmd скрипт для удаления старых файлов (в примере старше 10 дней):
forfiles /p C:\ /m *.rar /s /d -10 /c «cmd /c del @path /q»
Как удалить папки старше 7 дней с помощью forfiles
Кроме самих файлов не лишним будет удалять и папки, тем более если они будут пустые (без файлов). Код:
forfiles /p C:\downloads /s /d -7 /c «cmd /c rmdir /s del @path /q»
В этом примере я написал уже 7 дней. Для удаления папок мы используем rmdir, ключ /s — для сканирования вложенных папок, del — команда удаления, /q — удаление без подтверждения.
Феерическая расстановка точек над 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, не увеличивая размер файла образа. Но, с другой стороны, стандартные настройки — ближе к реальным условиям.
Создаем множество пустых файлов (будет работать несколько часов)
Кстати, если в начале файлы создавались достаточно быстро, то последующие добавлялись всё медленнее и медленнее, появлялись рандомные паузы, росло использование памяти ядром. Так что хранение большого числа файлов в плоской директории само по себе плохая идея.
Проверяем, что все айноды на ФС исчерпаны.
Размер файла директории ~360Мб
Теперь попробуем удалить эту директорию со всем её содержимым различными способами.
Тесты
После каждого теста сбрасываем кеш файловой системы
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 говорит, что не нужно сортировать список файлов.
Создает такую иерархию процессов:
Удаление через 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 — вполне нормально, если не накапливать результаты в памяти, а удалять файлы сразу.
Читайте также: