¿Por qué find -mtime +1 solo devuelve archivos anteriores a 2 días?

117

Estoy luchando por entender por qué la findmodificación de archivos interpreta la forma en que lo hace. Específicamente, no entiendo por qué -mtime +1no muestra archivos con menos de 48 horas de antigüedad.

Como ejemplo de prueba, creé tres archivos de prueba con diferentes fechas modificadas:

[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

Luego ejecuté find con el -mtime +1interruptor y obtuve el siguiente resultado:

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

Luego ejecuté find con el -mmin +1440y obtuve el siguiente resultado:

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

Según la página del manual para encontrar, entiendo que este es el comportamiento esperado:

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

Sin embargo, esto todavía no tiene sentido para mí. Entonces, si un archivo tiene 1 día, 23 horas, 59 minutos y 59 segundos, ¿ find -mtime +1ignora todo eso y lo trata como si tuviera 1 día, 0 horas, 0 minutos y 0 segundos? En cuyo caso, no es técnicamente más viejo que 1 día e ignorado?

No computa.

Mike B
fuente
77
Al principio también me pareció divertido, pero cuando consideras que mide la antigüedad de un archivo en días enteros, entonces hace exactamente lo que esperas. No dará archivos iguales a 1 día de antigüedad. Un archivo que tiene int (1.99) días de antigüedad no tiene> 1.
Octopus

Respuestas:

87

Bueno, la respuesta simple es, supongo, que su implementación de búsqueda está siguiendo el estándar POSIX / SuS, que dice que debe comportarse de esta manera. Citando de SUSv4 / IEEE Std 1003.1, Edición 2013, "buscar" :

-mtime n
     El primario evaluará como verdadero si el tiempo de modificación del archivo restado
     del tiempo de inicialización, dividido por 86400 (con cualquier resto descartado), es n.

(En otra parte de ese documento explica que nrealmente puede ser +n, y el significado de eso es "mayor que").

En cuanto a la razón por la norma dice que se comportan de esa manera, bueno, supongo que mucho en el pasado era un programador perezoso o no pensar en ello, y acabo de escribir el código C (current_time - file_time) / 86400. La aritmética de enteros C descarta el resto. Los scripts comenzaron dependiendo de ese comportamiento y, por lo tanto, se estandarizaron.

El comportamiento especificado también sería portátil a un sistema hipotético que solo almacenaba una fecha de modificación (no la hora). No sé si ese sistema ha existido.

derobert
fuente
3
find fue claramente diseñado para hacer solo trabajos de limpieza.
Kjeld Flarup
84

El argumento de -mtimese interpreta como el número de días completos en la antigüedad del archivo. -mtime +nsignifica estrictamente mayor que , -mtime -nsignifica estrictamente menor que.

Tenga en cuenta que con Bash, puede hacer lo más intuitivo:

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

para buscar archivos anteriores y posteriores a 24 horas, respectivamente.

(También es más fácil que escribir un argumento fraccionario -mtimepara cuando quieres una resolución en horas o minutos).

Evgeni Sergeev
fuente
2
Para enumerar esos archivos (solo regulares) con tamaños legibles por humanos y en orden cronológico, haga lo siguiente$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Evgeni Sergeev
1
Esto también tendrá el mismo efecto en que ambos comandos juntos aún perderán los archivos dentro de esa ventana de un minuto hace 24 horas.
Octopus
1
$(())es una sintaxis aritmética de shell simple, no es específica de Bash, cf. pubs.opengroup.org/onlinepubs/009695399/utilities/…
Josip Rodin
@JosipRodin ¡No, no necesariamente es cierto! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Dado que Bash es un SH "extendido", admite esta sintaxis, pero algunos otros shells no, por ejemplo, csh / tcsh.
t0r0X
@ t0r0X mi punto era que no es un bashism, sino que funciona en dash y zsh y todo lo demás sirve como convencional /bin/sh.
Josip Rodin el
45

¡Los períodos fraccionales de 24 horas se truncan! Eso significa que "find -mtime +1" dice que coincide con los archivos modificados hace dos o más días.

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

¿Lo siguiente solo puede funcionar en GNU?

find . -mmin +5 -mmin -10 # find files modified between
# 6 and 9 minutes ago
find / -mmin -10 # modified less than 10 minutes ago
Emir MurtaZa
fuente
Gracias, estaba tratando de entender por qué -mtime X era diferente a -mtime + X
Vnge
Me imagino que + X significa cortos para (X + 1, X + 2, X + 3, ...). :)
Eric Zheng
18

Entonces, si un archivo tiene 1 día, 23 horas, 59 minutos y 59 segundos, find -mtime +1 ignora todo eso y lo trata como si tuviera 1 día, 0 horas, 0 minutos y 0 segundos.

Si. Como man finddice, "cualquier parte fraccionaria se ignora". Si divide "1 día, 23 horas, 59 minutos y 59 segundos" entre "24 horas", puede obtener 1.9999, pero la parte .9999 se elimina y de repente el archivo tiene solo 1 día.

Martin von Wittich
fuente
18

-mtime Nsignifica archivos cuya edad A en días satisface NA < N +1. En otras palabras, selecciona los archivos que se modificaron por última vez entre N y N +1 días atrás.-mtime N

-mtime -Nsignifica archivos cuya edad A satisface A < N , es decir, archivos modificados hace menos de N días. Menos intuitivo, significa archivos cuya edad A satisface N +1 ≤ A , es decir, archivos modificados al menos N +1 días atrás.-mtime +N

Por ejemplo, -mtime 1selecciona archivos que se modificaron entre 1 y 2 días atrás. -mtime +1selecciona archivos que se modificaron hace al menos 2 días. Para modificar los archivos al menos hace 1 día, use -mtime +0.

La descripción "fue modificada por última vez hace 24 horas" es solo una aproximación, y no muy clara.

Si encuentra estas reglas difíciles de recordar, use un archivo de referencia en su lugar.

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

(La sintaxis "Hace 1 día" requiere GNU touch).

Gilles
fuente
3
Buena explicación, los primeros 3 párrafos deben agregarse a la documentación de find!
Melebius
4

Use -mmin, -amin, etc. para obtener resultados exactos

Eran Ben-Natan
fuente
66
Los -?minargumentos funcionan exactamente como los -?timeargumentos, excepto con minutos en lugar de días. Tampoco son "exactos".
Gilles
-2

Si desea exactamente archivos de 48 horas de antigüedad, no 2 días, entonces debe agregar --daystartsu findcomando. Esto te ayudara.

find . type -f -daystart -mtime +1
Aravind Goud
fuente
55
No, primero es -daystart(una extensión GNU), no --daystart. Entonces, -daystartsolo significa comparar las horas con el comienzo de hoy en lugar de la hora actual, por --daystart -mtime +1lo que informaría los archivos que se modificaron más de 48h / 2 horas antes del comienzo de hoy, por lo que generalmente los archivos que se modificaron rigurosamente antes de anteayer .
Stéphane Chazelas