Wiersz poleceń: rurociąg wyszukuje wyniki do rm

140

Próbuję wypracować polecenie, które usuwa pliki sql starsze niż 15 dni.

Znajdująca się część działa, ale nie rm.

rm -f | find -L /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups -type f  \( -name '*.sql' \) -mtime +15

Wyświetla listę dokładnie tych plików, które chcę usunąć, ale ich nie usuwa. Ścieżki są prawidłowe.

usage: rm [-f | -i] [-dIPRrvW] file ...
       unlink file
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120601.backup.sql
...
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120610.backup.sql

Co ja robię źle?

jerrygarciuh
źródło

Odpowiedzi:

274

Jesteś rzeczywiście potokiem rm„s wyjścia do wejścia find. To, czego chcesz, to użycie danych wyjściowych findjako argumentów do rm:

find -type f -name '*.sql' -mtime +15 | xargs rm

xargsjest poleceniem, które „konwertuje” swoje standardowe wejście na argumenty innego programu lub, jak dokładniej umieszcza je na manstronie,

budować i wykonywać wiersze poleceń ze standardowego wejścia

Zauważ, że jeśli nazwy plików mogą zawierać białe znaki, powinieneś to poprawić:

find -type f -name '*.sql' -mtime +15 -print0 | xargs -0 rm

Ale w rzeczywistości findma do tego skrót: -deleteopcja:

find -type f -name '*.sql' -mtime +15 -delete

Należy pamiętać o następujących ostrzeżeniach w man find:

  Warnings:  Don't  forget that the find command line is evaluated
  as an expression, so putting -delete first will make find try to
  delete everything below the starting points you specified.  When
  testing a find command line that you later intend  to  use  with
  -delete,  you should explicitly specify -depth in order to avoid
  later surprises.  Because -delete  implies  -depth,  you  cannot
  usefully use -prune and -delete together.

PS Zauważ, że bezpośrednie przesyłanie potokiem do rmnie jest opcją, ponieważ rmnie oczekuje nazw plików na standardowym wejściu. To, co obecnie robisz, to przepychanie ich do tyłu.

Lev Levitsky
źródło
1
Dzięki. Przeczytałem stronę podręcznika i spróbowałem tej flagi. Podaję pełną ścieżkę, ale wracam „/ usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: ścieżka względna potencjalnie niebezpieczna”. Każdy pomysł, dlaczego?
jerrygarciuh
1
@jerrygarciuh zajrzyj tutaj .
Lev Levitsky
dzięki. Nie jestem pewien, czy dobrze podążyłem za postem, ale kiedy emulowałem ich rozwiązanie i wstawiłem -delete na końcu polecenia, usunęło wszystkie pliki sql niezależnie od czasu modyfikacji ... ale nie miało ostrzeżenia, więc myślę, że to postęp ...
jerrygarciuh
1
@jerrygarciuh Ouch, mam nadzieję, że nic cennego nie zginęło ... manmówi: When testing a find command line that you later intend to use with -delete, you should explicitly specify -depth in order to avoid later surprises.Nie jestem pewien, jakie to ma znaczenie, biorąc pod uwagę inne opcje, z których korzystałeś, ale czy próbowałeś tego?
Lev Levitsky,
Nie, nie zrobiłem, ale nic nie zostało stracone. Te pliki są rsyncowane z innego serwera, na którym są również przechowywane.
jerrygarciuh
26
find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

Wybierze pliki /usr/www/bar/htdocsstarsze niż 15 dni i usunie je.

Jasne
źródło
Wolę Twoją odpowiedź niż zaakceptowaną ze względu na „miejsce w nazwie”. Lepiej obsługuje go polecenie „-exec” niż potok. Dzięki.
Slim Aloui
3

Inną prostszą metodą jest użycie locatepolecenia. Następnie prześlij wynik do xargs.

Na przykład,

locate file | xargs rm
Gautam Sreekumar
źródło
2

Zakładając, że nie jesteś w katalogu zawierającym pliki kopii zapasowej * .sql:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec rm -v {} \;

Powyższa opcja -v jest przydatna, ponieważ informuje o tym, które pliki są usuwane podczas ich usuwania.

Dla pewności lubię wymieniać pliki, które zostaną najpierw usunięte. Na przykład:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
Nick Little
źródło