Почему команда find -mtime +1 возвращает только файлы старше 2 дней?

117

Я изо всех сил , чтобы обернуть свой ум вокруг почему в findинтерпретируют файл время модификации так , как это делает. В частности, я не понимаю, почему -mtime +1файлы не отображаются менее чем за 48 часов.

В качестве примера теста я создал три тестовых файла с разными датами изменения:

[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

Затем я запустил find с -mtime +1переключателем и получил следующий вывод:

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

Затем я запустил find с -mmin +1440и получил следующий вывод:

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

Согласно man-странице для find, я понимаю, что это ожидаемое поведение:

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

Это все еще не имеет смысла для меня, хотя. Итак, если файлу 1 день, 23 часа, 59 минут и 59 секунд, find -mtime +1игнорировать все это и просто обрабатывать его как 1 день, 0 часов, 0 минут и 0 секунд? В каком случае, это технически не старше 1 дня и игнорируется?

Не считается.

Майк Б
источник
7
Сначала мне это тоже показалось смешным, но если учесть, что он измеряет возраст файлов в целых днях, то он делает именно то, что вы ожидаете. Это не даст файлы, равные 1-дневному возрасту. Файл с int (1.99) дней не> 1.
Octopus

Ответы:

87

Ну, простой ответ, я полагаю, заключается в том, что ваша реализация find соответствует стандарту POSIX / SuS, который говорит, что должен вести себя так. Цитирование из SUSv4 / IEEE Std 1003.1, издание 2013 г., «найти» :

-mtime n
     Первичный должен оценивать как истинный, если время модификации файла, вычтенное
     из времени инициализации, деленное на 86400 (с любым оставшимся остатком), равно n.

(В другом месте этого документа объясняется, что на nсамом деле может быть +n, и значение этого слова «больше чем»).

Относительно того, почему стандарт говорит, что он должен вести себя таким образом - ну, я думаю, давно в прошлом программист ленился или не думал об этом и просто писал код на Си (current_time - file_time) / 86400. Целочисленная арифметика C отбрасывает остаток. Сценарии начинались в зависимости от этого поведения, и поэтому оно было стандартизировано.

Поведение спецификации также переносимо на гипотетическую систему, в которой хранится только дата модификации (но не время). Я не знаю, существовала ли такая система.

derobert
источник
3
find был явно разработан только для очистки.
Кьелд Фларуп
84

Аргумент к -mtimeинтерпретируется как количество целых дней в возрасте файла. -mtime +nозначает строго больше , -mtime -nзначит строго меньше.

Обратите внимание, что с Bash вы можете сделать более интуитивно понятным:

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

найти файлы старше и новее 24 часов соответственно.

(Это также проще, чем вводить дробный аргумент -mtimeдля, когда вы хотите разрешение в часах или минутах.)

Евгений Сергеев
источник
2
Чтобы перечислить эти файлы (только обычные) с удобочитаемыми размерами и в хронологическом порядке, сделайте$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Евгений Сергеев
1
Это также будет иметь тот же эффект, что обе эти команды вместе по-прежнему будут пропускать файлы в одном минутном окне 24 часа назад.
Осьминог
1
$(())это простой арифметический синтаксис оболочки, это не относится к Bash, ср. pubs.opengroup.org/onlinepubs/009695399/utilities/…
Иосип Роден
@JosipRodin Нет, не обязательно правда! This chapter describes the syntax of that command language as it is used by the sh utility and [...], Поскольку Bash является «расширенным» SH, он поддерживает этот синтаксис, но некоторые другие оболочки этого не делают, например, csh / tcsh.
t0r0X
@ t0r0X моя точка зрения заключалась в том, что это не bashism, скорее, он работает в dash и zsh, и все остальное служит обычным /bin/sh.
Иосип Роден
45

Дробные 24-часовые периоды усекаются! Это означает, что «find -mtime +1» говорит о совпадении файлов, измененных два или более дней назад.

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

Следующее может работать только на GNU?

find . -mmin +5 -mmin -10 # find files modified between
# 6 and 9 minutes ago
find / -mmin -10 # modified less than 10 minutes ago
Эмир Муртаза
источник
Спасибо, я пытался выяснить, почему -mtime X отличается от -mtime + X
Vnge
Я думаю, что + X означает шорты для (X + 1, X + 2, X + 3, ...). :)
Эрик Чжэн
18

Так что, если файлу 1 день, 23 часа, 59 минут и 59 секунд, find -mtime +1 игнорирует все это и просто обрабатывает его как 1 день, 0 часов, 0 минут и 0 секунд?

Да. Как man findговорит «любая дробная часть игнорируется». Если вы разделите «1 день, 23 часа, 59 минут и 59 секунд» на «24 часа», вы можете получить 1,9999, но затем часть .9999 будет удалена, и внезапно файлу будет только 1 день.

Мартин фон Виттих
источник
18

-mtime Nозначает файлы, чей возраст A в днях соответствует NA < N +1. Другими словами, выбираются файлы, которые были в последний раз изменены от N до N +1 день назад.-mtime N

-mtime -Nозначает файлы, возраст которых A соответствует A < N , т.е. файлы, измененные менее N дней назад. Менее интуитивно, означает файлы, чей возраст A удовлетворяет N +1 ≤ A , то есть файлы, измененные по крайней мере N +1 дней назад.-mtime +N

Например, -mtime 1выбирает файлы, которые были изменены от 1 до 2 дней назад. -mtime +1выбирает файлы, которые были изменены не менее 2 дней назад. Чтобы получить файлы, измененные как минимум 1 день назад, используйте -mtime +0.

Описание «последний раз модифицировалось n * 24 часа назад» является лишь приблизительным и не очень понятным.

Если вам трудно запомнить эти правила, используйте вместо этого справочный файл.

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

(Синтаксис «1 день назад» требует GNU touch.)

жилль
источник
3
Хорошее объяснение, первые 3 абзаца должны быть добавлены в документацию find!
Мелебиус
4

Используйте -mmin, -amin и т. Д., Чтобы получить точные результаты

Эран Бен-Натан
источник
6
Эти -?minаргументы работают точно так же , как и -?timeаргументы , за исключением с минуты вместо дней. Они тоже не «точные».
Жиль
-2

Если вы хотите файлы размером 48 часов, а не 2 дня, добавьте их --daystartв свою findкоманду. Это поможет вам.

find . type -f -daystart -mtime +1
Аравинд Гауд
источник
5
Нет, сначала это -daystart(расширение GNU), нет --daystart. Затем -daystartпросто означает сравнение времени с началом сегодняшнего дня, а не с текущим, поэтому --daystart -mtime +1будет сообщать о файлах, которые были изменены более чем за 48 ч / 2 часа до начала сегодняшнего дня, поэтому обычно файлы, которые были изменены строго до позавчерашнего дня ,
Стефан Шазелас