Z wdziękiem usuwamy pliki starsze niż 30 dni

8

Mam folder pamięci podręcznej z co najmniej 15 000 plików.

Próbowałem tego:

find cache* -mtime +30 -exec rm {} \;

Ale to spowodowało, że mój serwer poleciał do nieba!

Czy jest jakieś szybsze / lepsze rozwiązanie?

Czy mogę ograniczyć prędkość lub iteracje tego polecenia?

Kristian
źródło
1
Jeśli cache*rozwija się do wielu plików, możesz spróbować czegoś takiego find . -name 'cache*' -mtime +30 -exec rm {} \;.
Jaap Eldering

Odpowiedzi:

10

Lubię używać tmpwatchdo tych rzeczy, to jest ostatni raz, gdy plik został zmodyfikowany. To proste i działa dobrze w wielu przypadkach:

tmpwatch -m 720 /path/to/cache

W przypadku Ubuntu sprawdź tmpreaperzamiast tego.

Jeśli chcesz sprawdzić ostatni dostęp do pliku, użyj następujących czynności:

tmpwatch -a 720 /path/to/cache

Nie możesz używać tmpwatch -a w systemach plików montowanych z noatime. nadal możesz użyć -m

WojonsTech
źródło
Używam Ubuntu 10.04.2 LTSi to polecenie nie istnieje ..
Kristian
2
@Kristian Sprawdź tmpreaperzamiast.
slhck
Jakieś pułapki przy korzystaniu z nich do zarządzania systemami plików zamontowanymi z opcją noatime?
AnonymousLurker
@AnonymousLurker Zmodyfikowałem dla ciebie odpowiedź
WojonsTech
6

Można uniknąć zaszczepiania nowego procesu dla każdego pliku za pomocą

find cache* -mtime +30 -delete
Chiborg
źródło
3

Spróbuj uruchomić powyższe z ładnym:

nice -n 39 find cache* -mtime +30 -exec rm -f {} ';'

W ten sposób ogromne obciążenie pojawi się tylko wtedy, gdy nic innego nie będzie musiało zostać uruchomione, w przeciwnym razie inne procesy będą miały pierwszeństwo (jeśli ich liczba jest mniejsza niż 19, tj. Maksymalna).

Zauważ, że argument opcji -n jest dodawany do domyślnej niceness, która waha się między -20 a 19. Użyłem 39, więc będzie bardzo przyjemnie, niezależnie od tego, jaka była pierwotna niceness.

DanielFetchinson
źródło
2

Jak skomentował chiborg, obciążenie wynika z uruchomienia rm dla każdego znalezionego pliku. Zauważyłem odpowiedź, która tmpwatchjest sugerowana jako alternatywa, która z pewnością działa dobrze. Nie jest to jednak konieczne.

Find może uruchomić polecenie wydane jednokrotnie, jeśli powiesz mu, aby zgromadziło znalezione pliki na liście takich argumentów:

find /path -name "*.moo" -exec rm {} \+

Czasami może to nie działać, ponieważ lista argumentów może być większa (w bajtach) niż maksymalna dozwolona przez powłokę (getconf ARG_MAX). Można to rozwiązać za pomocą xargs z opcją -L.

rozważ ten przykład:

$ echo 0 > /tmp/it; 
$ for i in {0..15000};do echo $i;done  |\
    xargs --no-run-if-empty -L 5000 ./tmp/xr.sh 
Iteration=0; running with 5000 arguments
Iteration=1; running with 5000 arguments
Iteration=2; running with 5000 arguments
Iteration=3; running with 1 arguments

$ cat tmp/xr.sh 
#!/bin/sh
IT=`cat /tmp/it`
echo Iteration=$IT\; running with $# arguments
let IT=IT+1
echo $IT > /tmp/it

Więc nie ma potrzeby instalowania dodatkowego oprogramowania, wszystko czego potrzebujesz to gnu-findutils:

find /path -mtime +30 -print0 | xargs -0 -L 5000 rm 
Ярослав Рахматуллин
źródło
niektórzy d00d uważali, że przydałoby się dodać -print0 i -0 do find i xargs. Argumenty te wymuszają, aby ich polecenia używały znaku zerowego (\ 0) zamiast znaku nowej linii (\ n) do oddzielenia argumentów. Jest to pomocne, gdy w nazwie pliku są spacje lub znaki nowej linii.
Ярослав Рахматуллин
(1) Nie musisz mówić \+; zwykły +jest wystarczająco dobry. (2) To nie „nie zadziała, ponieważ lista argumentów może urosnąć…”.  find  … -exec … {} +zrobi to samo, co xargszrobi; uruchomi polecenie tyle razy, ile będzie trzeba. Na przykład (jak w twoim przykładzie), jeśli masz od 15001 do 20000 plików, finduruchomiłby -execprogram (d rm) cztery razy.
G-Man mówi „Przywróć Monikę”