Mamy problem z nieporęcznym folderem z setkami tysięcy małych plików.
Jest tak wiele plików, że wykonanie rm -rf
zwraca błąd, a zamiast tego musimy zrobić coś takiego:
find /path/to/folder -name "filenamestart*" -type f -exec rm -f {} \;
Działa to, ale jest bardzo wolne i ciągle kończy się brak pamięci.
Czy jest na to lepszy sposób? Idealnie chciałbym usunąć cały katalog bez dbania o zawartą w nim zawartość.
linux
command-line
files
rm
Toby
źródło
źródło
rm -rf *
w folderze prawdopodobnie nie udaje się z powodu zbyt wielu argumentów; ale corm -rf folder/
jeśli chcesz usunąć cały katalog?rm -rf
?fsck
go, aby odzyskać nieużywane bloki dysku, ale takie podejście wydaje się ryzykowne i może nie być szybsze. Ponadto sprawdzenie systemu plików może obejmować rekurencyjne przechodzenie przez drzewo systemu plików.ccache
tak ogromne drzewo plików irm
trwało to tak długo (powodując spowolnienie całego systemu), znacznie szybciej było skopiować wszystkie inne pliki z systemu plików, sformatować je i skopiować z powrotem. Od tamtej pory tak masywne małe drzewa plików mają własny dedykowany system plików, więc możeszmkfs
bezpośrednio zamiastrm
.Odpowiedzi:
Korzystanie z rsync jest zaskakująco szybkie i proste.
Odpowiedź @ Sarath wspomniała o innym szybkim wyborze: Perl! Jego testy porównawcze są szybsze niż
rsync -a --delete
.Źródła:
źródło
rsync
może być szybszy niż zwykłyrm
, ponieważ gwarantuje usunięcie w prawidłowej kolejności, więc potrzeba mniej obliczeń btress. Zobacz tę odpowiedź serverfault.com/a/328305/105902-P
opcję do rsync, aby wyświetlić więcej, a także uważaj na składnię, ukośniki końcowe są obowiązkowe. Na koniec możesz uruchomić polecenie rsync po raz pierwszy z-n
opcją pierwszego uruchomienia suchego uruchomienia .-a
równa się-rlptgoD
, ale tylko do usunięcia-rd
jest konieczneKtoś na Twitterze zasugerował użycie
-delete
zamiast-exec rm -f{} \;
To poprawiło efektywność polecenia, ale wciąż używa rekurencji, aby przejść przez wszystko.
źródło
find
ma-delete
ifind
może inne .-delete
-exec rm
ze względów bezpieczeństwa i wydajności należy zawsze preferować, gdy są dostępne.Co powiesz na coś takiego:
find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f
Możesz ograniczyć liczbę plików do usunięcia jednocześnie, zmieniając argument parametru
-n
. Uwzględniono także nazwy plików ze spacjami.źródło
-n 20
bitu, ponieważ xargs i tak powinien ograniczyć się do akceptowalnych rozmiarów list argumentów.man xargs
:(...) max-chars characters per command line (...). The largest allowed value is system-dependent, and is calculated as the argument length limit for exec
. Tak-n
jest opcja dla takich przypadków, w których xargs nie może określić rozmiaru bufora CLI lub jeśli wykonane polecenie ma pewne ograniczenia.Sprytna sztuczka:
Jest bardzo intensywny, ale bardzo szybki. Zobacz https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html
źródło
rsync -a --delete
vs 43 dlalsdent
. Współczynnik 10x był dlatime ls -1 | wc -l
vstime ./dentls bigfolder >out.txt
(to jest częściowo rzetelne porównanie z powodu> file
vswc -l
).Rozwijając jeden z komentarzy, nie sądzę, że robisz to, co myślisz.
Najpierw stworzyłem ogromną liczbę plików, aby zasymulować twoją sytuację:
Potem spróbowałem tego, czego się nie spodziewałem i co brzmi jak robisz w pytaniu:
Ale to czyni pracę:
źródło
rm -Rf bigdirectory
kilka razy. Miałem katalog z tysiącami milionów podkatalogów i plików. Nie mogłem nawet uruchomićls
lubfind
czyrsync
w tym katalogu, ponieważ zabrakło pamięci. Polecenierm -Rf
kilkakrotnie kończyło pracę (brak pamięci), usuwając tylko część miliardów plików. Ale po wielu próbach w końcu zadziałało. Wydaje się być jedynym rozwiązaniem, jeśli problemem jest brak pamięci.Miałem okazję przetestować
-delete
w porównaniu do-exec rm \{\} \;
i dla mnie-delete
była odpowiedzią na ten problem.Za pomocą
-delete
usuniętych plików w folderze 400 000 plików co najmniej 1000 razy szybciej niżrm
.Artykuł „Jak usunąć dużą liczbę plików w systemie Linux” sugeruje, że jest on około trzy razy szybszy, ale w moim teście różnica była znacznie bardziej dramatyczna.
źródło
find -exec
wykonanierm
polecenia dla każdego pliku osobno, dlatego jest tak wolny.O
-delete
powyższej opcji: używam jej do usuwania dużej liczby (1M + est) plików w folderze tymczasowym, który utworzyłem i mimowolnie zapomniałem co noc czyścić. Przypadkowo zapełniłem mój dysk / partycję i nic więcej nie mogło ich usunąć opróczfind .
polecenia. Jest wolny, początkowo używałem:Ale zajęło to NIEZWYKLE czasu. Zaczęło się po około 15 minutach, aby usunąć niektóre pliki, ale domyślam się, że usuwało mniej niż 10 na sekundę po tym, jak w końcu się zaczęło. Próbowałem więc:
zamiast tego i pozwalam mu działać teraz. Wygląda na to, że działa szybciej, chociaż BARDZO obciąża procesor, czego nie było inne polecenie. Działa już od godziny i myślę, że odzyskuję miejsce na dysku, a partycja stopniowo „odchudza się”, ale wciąż zajmuje to bardzo dużo czasu. Poważnie wątpię, że działa 1000 razy szybciej niż inne. Jak we wszystkich rzeczach, chciałem tylko zwrócić uwagę na kompromis w przestrzeni w czasie. Jeśli masz do dyspozycji przepustowość procesora (my), uruchom drugą. Uruchomił mój procesor (
uptime
raporty):Zauważyłem, że średnia wartość obciążenia przekracza 30,00, co nie jest dobre dla zajętego systemu, ale dla naszego, który jest zwykle lekko obciążony, jest OK przez kilka godzin. Sprawdziłem większość innych rzeczy w systemie i one wciąż reagują, więc na razie jesteśmy w porządku.
źródło
exec
, prawie na pewno nie chcesz używać-ls
i robieniefind . -type f -exec rm '{}' +
+ jest szybsze, ponieważ da to tyle argumentów do rm, ile może obsłużyć naraz.find … -delete
przeznice
lubionice
, co może pomóc. Może więc zmienić niektóre opcje montowania na ustawienia mniej odporne na awarie. (I, oczywiście, w zależności od tego, co jeszcze jest w systemie plików, często najszybszym sposobem na usunięcie wszystkiegomkfs
.)1
dla maszyny jednordzeniowej jest taki sam jak loadavg64
w systemie 64-rdzeniowym - co oznacza, że każdy procesor jest zajęty przez 100% czasu.Istnieje kilka metod usuwania dużej liczby plików w systemie Linux. Możesz użyć opcji Znajdź z opcją usuwania, która jest szybsza niż opcja exec. Następnie możesz użyć perla unlink, a nawet rsync. Jak usunąć dużą liczbę plików w systemie Linux
źródło
Rozważ użycie woluminu Btrfs i po prostu usuń cały wolumin dla takiego katalogu z dużą liczbą plików.
Alternatywnie możesz utworzyć plik obrazu FS, a następnie odmontować i usunąć jego plik, aby usunąć wszystko na raz naprawdę szybko.
źródło
Zakładając, że mam
parallel
zainstalowany GNU , użyłem tego:parallel rm -rf dir/{} ::: `ls -f dir/`
i było wystarczająco szybko.
źródło
Usuwanie NAPRAWDĘ DUŻYCH katalogów wymaga innego podejścia, jak dowiedziałem się z tej strony - będziesz musiał użyć ionice. Zapewnia to (przy -c3), że usuwanie zostanie wykonane tylko wtedy, gdy system ma na to czas IO. Obciążenie systemu nie wzrośnie i wszystko pozostanie responsywne (chociaż mój czas procesora na znalezienie był dość wysoki i wynosił około 50%).
źródło
+
zamiast\;
sprawiłoby, że byłoby to szybsze, ponieważ przekazuje więcej argumentów do rm naraz, mniej rozwidleniaionice -c3 find <dir> -type f -delete
powinien działać w folderze głównym
źródło
ls
nie będzie działać z powodu ilości plików w folderze. Właśnie dlatego musiałem skorzystaćfind
, dzięki.ls -f
, co wyłącza sortowanie. Sortowanie wymaga załadowania całego katalogu do pamięci w celu posortowania. Niesortowanels
powinny być w stanie przesyłać strumieniowo swoje dane wyjściowe.find . -print0 | xargs -0 rm
, który użyje znaku NULL jako separatora nazw plików.Za wskazówkę Izkaty powyżej:
To prawie działało - lub by działało - ale miałem pewne problemy z pozwoleniem; pliki znajdowały się na serwerze, ale nadal nie rozumiem, skąd wziął się ten problem z uprawnieniami. W każdym razie Terminal poprosił o potwierdzenie każdego pliku. Liczba plików wynosiła około 20 000, więc nie było takiej opcji. Po „-r” dodałem opcję „-f”, więc całe polecenie brzmiało „ rm -r -f nazwa_folderu / ”. Potem wydawało się, że działa dobrze. Jestem nowicjuszem w Terminalu, ale myślę, że to było w porządku, prawda? Dzięki!
źródło
W zależności od tego, jak dobrze musisz pozbyć się tych plików, sugeruję użycie
shred
.jeśli chcesz wyczyścić katalog, ale nie możesz go usunąć i odtworzyć, sugeruję przeniesienie go i odtworzenie go natychmiast.
jest to szybsze, wierzcie lub nie, ponieważ trzeba zmienić tylko jeden i-węzeł. Pamiętaj: tak naprawdę nie można zrównoważyć tego smaku na komputerze wielordzeniowym. Sprowadza się to do dostępu do dysku, który jest ograniczony przez macierz RAID lub to, co masz.
źródło
shred
nie będzie działać z wieloma nowoczesnymi systemami plików.Jeśli masz miliony plików i każde powyższe rozwiązanie powoduje stres w systemie, możesz spróbować inspiracji:
Plik
nice_delete
:A teraz usuń pliki:
Find utworzy partie (patrz
getconf ARG_MAX
) kilkudziesięciu tysięcy plików i przekaże jenice_delete
. Spowoduje to utworzenie jeszcze mniejszych partii, aby umożliwić spanie po wykryciu przeciążenia.źródło
Jeśli chcesz pozbyć się wielu plików tak szybko, jak to możliwe,
ls -f1 /path/to/folder/with/many/files/ | xargs rm
może działać dobrze, ale lepiej nie uruchamiaj ich w systemach produkcyjnych, ponieważ w systemie mogą wystąpić problemy z operacjami we / wy, a aplikacje mogą utknąć podczas operacji usuwania.Ten skrypt działa dobrze dla wielu plików i nie powinien wpływać na ioload systemu.
źródło