Есть ли более быстрый способ удалить каталог, чем «rm -rf»?

32

У меня есть папка с множеством файлов, и «rm -rf» занимает много времени. Есть ли более быстрый способ удалить каталог и его содержимое (подкаталоги и т. Д.)?

Мухаммед Могими
источник
Для тех, кто заинтересован, смотрите: slashroot.in/comment/1286#comment-1286 найти козыри Perl козыри rsync
Rinzwind

Ответы:

33

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

rm так же хорошо, как и получает.


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

Если вы хотите удалить каталог и все в нем, я предлагаю вам:

rm -rf path/to/directory

rmбудет внутренне список файлов и каталогов , это будет удалить. И это все в скомпилированный C . Это две причины, по которым это быстрее всего.

Это очень многозначительно не то же самое, rm -rf path/to/directory/*что расширение на уровне оболочки и передача множества аргументов rm. Затем rmнужно разобрать их, а затем отобрать у каждого. Это намного медленнее.

Так же, как «эталон», который сравнивает, find path/to/directory -exec {} \;это чепуха. Он запускается rmодин раз для каждого найденного файла. Так медленно. Find может использовать аргументы команд сборки в стиле xargs, -exec rm {} +но это так же медленно, как и расширение. Вы можете вызвать, -deleteкоторый использует внутренний unlinkвызов ядра (как это rmделает), но сначала это будет работать только для файлов.

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


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

Или используйте более быстрый диск. Если у вас есть тонны оперативной памяти, использование /dev/shm(RAM-диск) может быть идеей.

Оли
источник
На самом деле вы не можете использовать unlinkсистемный вызов для каталогов (вы получите EISDIRошибку), поэтому первый вариант невозможен.
Джеймс Хенстридж
Будет ли mv to / tmp быстрее? Кажется, мв тоже много времени занимает.
Мухаммед Могими,
@MohammadMoghimi: mvмежду различными файловыми системами / разделами cpследует a, за которым следует a rm.
энзотиб
3
@enzotib Однако, если /tmpнаходится в той же файловой системе, мне интересно, будет ли mvперезапуск быстрее? Я не уверен, что все /tmpравно очищается с помощью rm.
Sparhawk
1
rsyncв этом тесте это происходит быстрее, чем rm -rf: web.archive.org/web/20130929001850/http://linuxnote.net/…
schmijos
11

Иногда find $DIR_TO_DELETE -type f -deleteбыстрее чем rm -rf.

Вы также можете попробовать mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE.

Наконец, если вам нужно удалить содержимое целого раздела, скорее всего, будет быстрее umount, mkfsи повторно mount.

mivk
источник
1
не type -fобозначать файл, а не каталог? Кроме того, при добавлении -printотображаются файлы по мере их удаления.
Leetbacoon
8

Если вам не нужно свободного места, самый быстрый способ - отложить удаление и сделать это в фоновом режиме:

  • mkdir .delete_me
  • mv большой каталог-что-я-хочу-ушел .delete_me

Затем создайте crontab, который делает это в фоновом режиме, в тихое время, с низким приоритетом ввода / вывода:

3 3 * * * root ionice -c 3 nice find /path/to/.delete_me -maxdepth 1 ! -name \. -exec echo rm -rf "{}" +

Заметки:

  • проверьте вывод перед удалением эха в crontab!
  • каталог .delete_me должен находиться в одной файловой системе - в случае, если это не очевидно для всех.

Обновление: я нашел удобный прием для параллельного запуска нескольких rm - это поможет, если у вас большой дисковый массив:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • Глубина, чтобы сделать глубинный обход.

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

  • -d \ n для обработки пробелов в именах файлов.

  • -P и -n управляют степенью параллелизма (проверьте страницу man).

ссылка: http://blog.liw.fi/posts/rm-is-too-slow/#comment-3e028c69183a348ee748d904a7474019

Обновление 2 (2018): С ZFS, поставляемой с Ubuntu 18.04, я использую его для всего и создам новый набор данных для любого большого проекта. Если вы планируете заранее и делаете это заранее, вы можете просто «zfs уничтожить» файловую систему, когда закончите. ;-)

Я использовал инструкции из вики zfsonlinux, чтобы установить Ubuntu на ZFS изначально: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS

Лестер Чунг
источник
2
Вместо этой последней команды используйте find target_dir -maxdepth 3 -depth -type d -print0 | xargs -0 -P 5 rm -rf. -depthОпция указывает findв список детей первого.
Муру
2

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

Например, у меня работает зона для игры в гольф. Я разработал Linux-рейд объемом 1,5 ТБ для обработки огромного количества данных, которые она записывает за день (12 камер), и то, как она работала на диске 120 ГБ, выше моего понимания. Короче говоря, папка со всеми захваченными данными составляет около 1,4 ТБ ее хранилища. Много чистить

Переустанавливать ZM и очищать старую библиотеку объемом 1,4 ТБ не очень весело, поскольку удаление старых изображений может занять 1-2 дня.

Истинно индексированная ФС позволяет удалить каталог и знает, что данные в нем мертвы, а обнуление данных - пустая трата нашего времени и ресурсов ПК. Это должна быть опция обнуления удаленных данных. RM просто долго в реальном мире на ext4.

Ответ: Рекурсивное удаление всех файлов будет быстрее, но вам все равно придется выделить время для запуска FSCK.

Создайте сценарий, выполняющий рекурсивную команду «FOR», которая может «отсоединить» все файлы в ваших папках, а затем просто нажмите rm или rmdir для всех папок, чтобы очистить его. Вручную запустите FSCK, чтобы обнулить остальные данные, когда это будет удобно. Вроде ленивый не выписал извините :).

Адам Лазо
источник
0

Хотя это и бесполезно, если вы хотите очистить существующий каталог, я упомяну, что возможной стратегией, если вы знаете, что у вас будет каталог с большим количеством файлов, которые вам необходимо регулярно очищать, является размещение каталога в собственной файловой системе ( например , раздел). Затем, когда вам нужно очистить его, размонтируйте его, запустите и установите mkfsего заново. Например, OpenBSD рекомендует сделать это для/usr/obj тех случаев, когда во время сборки системы создается много файлов, и их необходимо удалить до следующей сборки.

fkraiem
источник