Удаляем огромное количество файлов в директориях файловых систем Linux

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


1. Вполне юзабельно если в каталоге меньше 100к файлов.
rm -rf /your/directory
2. Используем find и 2 способа удаления
Вызываем rm на каждый файл
find /your/directory/ -type f -exec rm -v {} \;
Удаление средствами find
find /your/directory/ -type f -delete -print
3. Используем ls -f и xargs
cd /your/directory/ ; ls -f . | xargs -n 100 rm
4. rsync и синхронизация с пустой директорией.
rsync -av --delete empty_dir /your/directory/
Учтите, что все будет позаимствовано с директории empty_dir и владелец тоже.

Лично мне по нраву 3 и 4 способ, они проявили себя очень неплохо, так же для ленивых и аккуратных можно использовать Midnight commander с каталогами до 1 миллиона файлов справляется.

UPD 05.11.2015
Сегодня вновь столкнулся с подобной проблемой, все выше перечисленные способы не помогли, пришлось воспользоваться программой из статьи на хабре [ http://habrahabr.ru/post/152193/ ]
Листинг:
#define _GNU_SOURCE
#include <dirent.h>     /* Defines DT_* constants */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

struct linux_dirent {
        long           d_ino;
        off_t          d_off;
        unsigned short d_reclen;
        char           d_name[];
        };

#define BUF_SIZE 1024*30

int
main(int argc, char *argv[])
{
    int fd, nread;
    char buf[BUF_SIZE];
    struct linux_dirent *d;
    int bpos;
    int deleted;
    char d_type;
    char temp[100];

    fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
    if (fd == -1)
            handle_error("open");
            
    deleted = 0;

    nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
    
    if (nread == -1)
            handle_error("getdents");

    if (nread != 0) {
        for (bpos = 0; bpos < nread;) {
            d = (struct linux_dirent *) (buf + bpos);

            d_type = *(buf + bpos + d->d_reclen - 1);

            if(d->d_ino && d->d_ino != 22332748 && d->d_ino != 22332761) { // тут я прописал inode самой директории и директории верхнего уровня, чтобы он не пытался удалять файлы "." и ".." - принимаю подсказки, как это сделать лучше
                sprintf(temp,"%s/%s", argv[1], (char *) d->d_name);
                remove(temp);
                deleted += 1;
            }

            bpos += d->d_reclen;
        }
    }
    
    printf("deleted %d\n", deleted);

    exit(EXIT_SUCCESS);
}
Компиляция:
gcc cleardir.c -o cleardir
Использование:
./cleardir mod-tmp2
Если хотите что бы за раз удалялось гораздо больше файлов, измените константу #define BUF_SIZE 1024*30. Я 30 изменил на 100 и вместо 768 файлов за раз стало удаляться по 2560.

Комментарии ()

    Есть вопрос или предложение пиши в Telegram @cloudsv

    MTProto прokси для Telegram

    Прямой эфир

    cloudsv 01 октября 2019, 11:00
    Arch Linux Локальный редирект порта в Linux 0
    cloudsv 25 августа 2019, 19:14
    О жизни Социальная сеть от Яндекса Aura 0
    cloudsv 31 июля 2019, 00:34
    О жизни 33 year old 0
    cloudsv 25 июня 2019, 21:29
    Telegram Полезные боты в Telegram 0
    cloudsv 24 октября 2018, 00:27
    О жизни Обновление Scala Rider G4 11
    cloudsv 21 октября 2018, 23:16
    Arch Linux Памятка по основным утилитам Linux 0