Dlaczego funkcja find -mtime +1 zwraca tylko pliki starsze niż 2 dni?


116

Jestem stara się owinąć wokół zdanie dlaczego te findinterpretuje plik czasy modyfikacji sposób to robi. W szczególności nie rozumiem, dlaczego -mtime +1nie wyświetla plików starszych niż 48 godzin.

Jako przykładowy test stworzyłem trzy pliki testowe z różnymi zmodyfikowanymi datami:

[root@foobox findtest]# ls -l
total 0
-rw-r--r-- 1 root root 0 Sep 25 08:44 foo1
-rw-r--r-- 1 root root 0 Sep 24 08:14 foo2
-rw-r--r-- 1 root root 0 Sep 23 08:14 foo3

Następnie uruchomiłem find z -mtime +1przełącznikiem i uzyskałem następujące dane wyjściowe:

[root@foobox findtest]# find -mtime +1
./foo3

Następnie uruchomiłem find z -mmin +1440i otrzymałem następujące dane wyjściowe:

[root@foobox findtest]# find -mmin +1440
./foo3
./foo2

Jeśli chodzi o stronę podręcznika wyszukiwania, rozumiem, że jest to oczekiwane zachowanie:

 -mtime n
        File’s  data was last modified n*24 hours ago.  See the comments
        for -atime to understand how rounding affects the interpretation
        of file modification times.


-atime n
       File  was  last  accessed n*24 hours ago.  When find figures out
       how many 24-hour periods ago the file  was  last  accessed,  any
       fractional part is ignored, so to match -atime +1, a file has to
       have been accessed at least two days ago.

Jednak nadal nie ma to dla mnie sensu. Więc jeśli plik ma 1 dzień, 23 godziny, 59 minut i 59 sekund, find -mtime +1ignoruje to wszystko i traktuje go tak, jakby miał 1 dzień, 0 godzin, 0 minut i 0 sekund? W takim razie nie jest technicznie starszy niż 1 dzień i jest ignorowany?

Nie… nie… oblicza.


7
Na początku też wydawało mi się to śmieszne, ale jeśli weźmiesz pod uwagę, że mierzy wiek plików w dniach całkowitych, to robi dokładnie to, czego można się spodziewać. Nie da plików w wieku 1 dnia. Plik, który ma int (1.99) dni, nie ma> 1.
Octopus

Odpowiedzi:


86

Cóż, prosta odpowiedź brzmi, jak sądzę, że twoja implementacja find jest zgodna ze standardem POSIX / SuS, co oznacza, że ​​musi się tak zachowywać. Cytowanie z SUSv4 / IEEE Std 1003.1, wydanie 2013, „znajdź” :

-mtime n
     Wartość podstawowa będzie oceniana jako prawda, jeśli czas modyfikacji pliku odjęty
     od czasu inicjalizacji, podzielony przez 86400 (z resztą odrzuconą), wynosi n.

(W innym miejscu tego dokumentu wyjaśniono, że ntak naprawdę może być +n, i znaczenie tego jako „większe niż”).

Dlaczego średnia mówi powinien zachowywać się w ten sposób, dobrze, to myślę, że długo w przeszłości programista leniwy albo nie myśleć o tym i po prostu napisał kod C (current_time - file_time) / 86400. A arytmetyka liczb całkowitych C odrzuca resztę. Skrypty zaczęły się w zależności od tego zachowania, dlatego zostały ujednolicone.

Określone zachowanie będzie również przenośne w hipotetycznym systemie, w którym przechowywana jest tylko data modyfikacji (a nie godzina). Nie wiem, czy taki system istniał.


2
find został wyraźnie zaprojektowany wyłącznie do czyszczenia.
Kjeld Flarup,

83

Argument to -mtimejest interpretowany jako liczba pełnych dni w wieku pliku. -mtime +noznacza zdecydowanie więcej niż , -mtime -noznacza zdecydowanie mniej niż.

Pamiętaj, że dzięki Bash możesz robić bardziej intuicyjne:

$ find . -mmin +$((60*24))
$ find . -mmin -$((60*24))

aby znaleźć pliki odpowiednio starsze i nowsze niż 24 godziny.

(Jest to również łatwiejsze niż wpisanie ułamkowego argumentu, -mtimegdy chcesz uzyskać rozdzielczość w godzinach lub minutach.)


2
Aby wyświetlić listę tych plików (tylko zwykłe) o rozmiarach czytelnych dla ludzi oraz w porządku chronologicznym, wykonaj$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Evgeni Sergeev

1
Będzie to miało również ten sam efekt, że oba te polecenia razem nadal będą pomijać pliki w tym jednominutowym oknie 24 godziny temu.
Octopus,

1
$(())jest zwykłą składnią arytmetyczną, nie jest specyficzna dla Bash, por. pubs.opengroup.org/onlinepubs/009695399/utilities/…
Josip Rodin

@JosipRodin Nie, niekoniecznie prawda! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Ponieważ Bash jest „rozszerzonym” SH, obsługuje tę składnię, ale niektóre inne powłoki nie, np. Csh / tcsh.
t0r0X

@ t0r0X miałem na myśli, że to nie jest bashizm, działa raczej w myślniku i zsh i cokolwiek innego służy jako konwencjonalne /bin/sh.
Josip Rodin

44

Ułamkowe okresy 24-godzinne są skracane! Oznacza to, że „find -mtime +1” mówi o dopasowaniu plików zmodyfikowanych dwa lub więcej dni temu.

find . -mtime +0 # find files modified greater than 24 hours ago
find . -mtime 0 # find files modified between now and 1 day ago
# (i.e., in the past 24 hours only)
find . -mtime -1 # find files modified less than 1 day ago (SAME AS -mtime 0)
find . -mtime 1 # find files modified between 24 and 48 hours ago
find . -mtime +1 # find files modified more than 48 hours ago

Poniższe może działać tylko na GNU?

find . -mmin +5 -mmin -10 # find files modified between
# 6 and 9 minutes ago
find / -mmin -10 # modified less than 10 minutes ago

Dzięki, próbowałem dowiedzieć się, dlaczego -mtime X był inny niż -mtime + X
Vnge

Myślę, że + X oznacza skróty dla (X + 1, X + 2, X + 3, ...). :)
Eric Zheng,

18

Więc jeśli plik ma 1 dzień, 23 godziny, 59 minut i 59 sekund, znajdź -mtime +1 ignoruje to wszystko i traktuje go tak, jakby miał 1 dzień, 0 godzin, 0 minut i 0 sekund?

Tak. Jak man findmówi „każda część ułamkowa jest ignorowana”. Jeśli podzielisz „1 dzień, 23 godziny, 59 minut i 59 sekund” na „24 godziny”, możesz otrzymać 1,9999, ale część .9999 zostanie następnie usunięta i nagle plik ma tylko 1 dzień.


18

-mtime Noznacza pliki, których wiek A w dniach spełnia NA < N +1. Innymi słowy, wybiera pliki, które były ostatnio modyfikowane między N a N +1 dni temu.-mtime N

-mtime -Noznacza pliki, których wiek A spełnia A < N , tj. pliki zmodyfikowane mniej niż N dni temu. Mniej intuicyjnie oznacza pliki, których wiek A spełnia N +1 ≤ A , tj. Pliki zmodyfikowane co najmniej N +1 dni temu.-mtime +N

Na przykład -mtime 1wybiera pliki, które zostały zmodyfikowane od 1 do 2 dni temu. -mtime +1wybiera pliki, które zostały zmodyfikowane co najmniej 2 dni temu. Aby zmodyfikować pliki co najmniej 1 dzień temu, użyj -mtime +0.

Opis „ostatnio zmodyfikowano n * 24 godziny temu” jest jedynie przybliżeniem i nie jest zbyt jasny.

Jeśli te reguły są trudne do zapamiętania, użyj pliku referencyjnego.

touch -d '1 day ago' cutoff
find . -newer cutoff

(Składnia „1 dzień temu” wymaga GNU touch.)


3
Ładne wyjaśnienie, pierwsze 3 akapity należy dodać do dokumentacji find!
Melebius

4

Użyj -mmin, -amin itp., Aby uzyskać dokładne wyniki


6
Te -?minargumenty działają dokładnie tak samo jak -?timeargumenty z wyjątkiem kilku minut zamiast dni. Nie są też „dokładne”.
Gilles

-2

Jeśli chcesz dokładnie 48 godzinach-stare pliki, a nie 2 dni, a następnie należy dodać --daystartw findkomendzie. To ci pomoże.

find . type -f -daystart -mtime +1

5
Nie, najpierw to -daystart(rozszerzenie GNU), nie --daystart. Następnie -daystartoznacza po prostu porównanie czasów z początkiem dzisiejszego dnia zamiast bieżącego, więc --daystart -mtime +1zgłosiłbym pliki, które zostały zmodyfikowane więcej niż 48 godzin / 2 godziny przed początkiem dzisiejszego dnia, więc zazwyczaj pliki, które zostały zmodyfikowane ostro przed dniem wczorajszym .
Stéphane Chazelas
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.