168

I'm struggling to wrap my mind around why the find interprets file modification times the way it does. Specifically, I don't understand why the -mtime +1 doesn't show files less than 48 hours old.

As an example test I created three test files with different modified dates:

[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

I then ran find with the -mtime +1 switch and got the following output:

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

I then ran find with the -mmin +1440 and got the following output:

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

As per the man page for find, I understand that this is expected behavior:

 -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.

This still doesn't make sense to me though. So if a file is 1 day, 23 hours, 59 minutes, and 59 seconds old, find -mtime +1 ignores all that and just treats it like it's 1 day, 0 hours, 0 minutes, and 0 seconds old? In which case, it's not technically older that 1 day and ignored?

Does... not... compute.

2
  • 8
    At first it seemed funny to me too, but when you consider that it measures a files age in integer days, then it does exactly what you'd expect. It won't give files equal to 1 day old. A file that is int(1.99) days old is not > 1.
    – Octopus
    Commented Sep 19, 2014 at 20:20
  • Think about how humans treat age colloquially. If somebody is 79.9 years old, you say they are 79 years old. So if you are looking for a human over 79 years old, then you are looking for a human that is > 79.99999 years old i.e. >= 80 years old. People look at age as integers and round it down and see each age as a range.
    – barlop
    Commented May 7, 2020 at 0:08

7 Answers 7

121

The argument to -mtime is interpreted as the number of whole days in the age of the file. -mtime +n means strictly greater than, -mtime -n means strictly less than.

Note that with Bash, you can do the more intuitive:

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

to find files older and newer than 24 hours, respectively.

(It's also easier than typing in a fractional argument to -mtime for when you want resolution in hours or minutes.)

5
  • 2
    To list those files (regular only) with human-readable sizes and in chronological order, do $ find . -type f -mmin -$((60*24)) -exec ls -halt {} + Commented Feb 4, 2014 at 1:45
  • 2
    This will also have the same effect in that both of those commands together will still miss the files inside that one minute window 24 hours ago.
    – Octopus
    Commented Sep 19, 2014 at 20:21
  • 2
    $(()) is plain shell arithmetic syntax, it's not specific to Bash, cf. pubs.opengroup.org/onlinepubs/009695399/utilities/… Commented Jul 22, 2015 at 20:28
  • @JosipRodin No, not necessarily true! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Since Bash is a "extended" SH, it supports this syntax, but some other shells don't, e.g. csh/tcsh.
    – t0r0X
    Commented Jan 29, 2016 at 17:18
  • @t0r0X my point was that it's not a bashism, rather, it works in dash and zsh and whatever else serves as a conventional /bin/sh. Commented Jan 29, 2016 at 21:49
106

Well, the simple answer is, I guess, that your find implementation is following the POSIX/SuS standard, which says it must behave this way. Quoting from SUSv4/IEEE Std 1003.1, 2013 Edition, "find":

-mtime n
     The primary shall evaluate as true if the file modification time subtracted
     from the initialization time, divided by 86400 (with any remainder discarded), is n.

(Elsewhere in that document it explains that n can actually be +n, and the meaning of that as "greater than").

As to why the standard says it shall behave that way—well, I'd guess long in the past a programmer was lazy or not thinking about it, and just wrote the C code (current_time - file_time) / 86400. C integer arithmetic discards the remainder. Scripts started depending on that behavior, and thus it was standardized.

The spec'd behavior would also be portable to a hypothetical system that only stored a modification date (not time). I don't know if such a system has existed.

1
  • 3
    find was clearly designed to do cleanup jobs only. Commented Jan 19, 2017 at 10:47
69

Fractional 24-hour periods are truncated! That means that “find -mtime +1” says to match files modified two or more days ago.

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

The following may only work on GNU?

find . -mmin +5 -mmin -10 # find files modified between
# 6 and 9 minutes ago
find / -mmin -10 # modified less than 10 minutes ago
3
  • Thanks, I was trying to figure out why -mtime X was different than -mtime +X
    – Vnge
    Commented May 20, 2016 at 16:06
  • I figure that +X means shorts for (X+1, X+2, X+3, ... ). :)
    – Eric Zheng
    Commented Dec 22, 2016 at 6:00
  • links to all the source documents confuse the simple answer. Examples matter. its good documentation. Lets do more of them ! I like this answer Commented Dec 3, 2019 at 4:32
27

-mtime N means files whose age A in days satisfies NA < N+1. In other words, -mtime N selects files that were last modified between N and N+1 days ago.

-mtime -N means files whose age A satisfies A < N, i.e. files modified less than N days ago. Less intuitively, -mtime +N means files whose age A satisfies N+1 ≤ A, i.e. files modified at least N+1 days ago.

For example, -mtime 1 selects files that were modified between 1 and 2 days ago. -mtime +1 selects files that were modified at least 2 days ago. To get files modified at least 1 day ago, use -mtime +0.

The description “was last modified n*24 hours ago” is only an approximation, and not a very clear one.

If you find these rules hard to remember, use a reference file instead.

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

(The syntax “1 day ago” requires GNU touch.)

1
  • 6
    Nice explanation, the first 3 paragraphs should be added to the documentation of find!
    – Melebius
    Commented Sep 18, 2017 at 6:14
20

So if a file is 1 day, 23 hours, 59 minutes, and 59 seconds old, find -mtime +1 ignores all that and just treats it like it's 1 day, 0 hours, 0 minutes, and 0 seconds old?

Yes. Like man find says, "any fractional part is ignored". If you divide "1 day, 23 hours, 59 minutes, and 59 seconds" through "24 hours", you may get 1.9999, but the .9999 part is then stripped and suddenly the file is only 1 day old.

5

Use -mmin, -amin, etc to get exact results

1
  • 8
    The -?min arguments work exactly like the -?time arguments except with minutes instead of days. They aren't “exact” either. Commented May 2, 2015 at 20:53
-3

If you want exactly 48-hours-old files, not 2 days, then you should add --daystart in your find command. This will help you.

find . type -f -daystart -mtime +1
1
  • 5
    No, first it's -daystart (a GNU extension), not --daystart. Then, -daystart just means to compare times with the beginning of today instead of the current time, so --daystart -mtime +1 would report files that were modified more that 48h / 2 hours before the beginning of the today, so usually files that were modified strickly before the day before yesterday. Commented Jan 13, 2016 at 10:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .