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?

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.


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.


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

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 {} \;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.