Pourquoi trouver -mtime +1 ne renvoie-t-il que les fichiers de plus de 2 jours?

117

J'ai du mal à comprendre pourquoi l' findinterprétation des délais de modification des fichiers est la même. Plus précisément, je ne comprends pas pourquoi les -mtime +1fichiers de moins de 48 heures ne sont pas affichés.

À titre d'exemple, j'ai créé trois fichiers de test avec différentes dates de modification:

[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

J'ai ensuite exécuté trouver avec le -mtime +1commutateur et obtenu la sortie suivante:

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

J'ai alors couru trouver avec -mmin +1440et obtenu la sortie suivante:

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

D'après la page de manuel de find, je comprends qu'il s'agit du comportement attendu:

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

Cela n'a toujours pas de sens pour moi cependant. Ainsi, si un fichier a 1 jour, 23 heures, 59 minutes et 59 secondes, find -mtime +1ignore tout cela et le traite comme s'il en avait 1 jour, 0 heure, 0 minute et 0 secondes? Dans quel cas, techniquement, il n’est pas plus vieux qu’un jour et est ignoré?

Est-ce que ... pas ... calculer.

Mike B
la source
7
Au début, cela me semblait drôle aussi, mais si vous considérez que cela mesure l’âge des fichiers en jours, il fait exactement ce que vous attendez. Les fichiers ne seront pas égaux à 1 jour. Un fichier qui a int (1.99) jours n’est pas> 1.
Octopus

Réponses:

87

Eh bien, la réponse simple est, je suppose, que votre implémentation de find suit le standard POSIX / SuS, qui dit que cela doit se comporter de cette manière. Citant SUSv4 / IEEE Standard 1003.1, édition 2013, "trouver" :

-mtime n
     Le primaire doit être évalué comme étant vrai si le temps de modification du fichier soustrait
     du temps d'initialisation, divisé par 86400 (sans tenir compte du reste), est n.

(Ailleurs dans ce document, il est expliqué que cela npeut effectivement être +net que sa signification est "plus grand que").

Quant à savoir pourquoi la norme dit qu'il doit se comporter de cette façon-bien, je suppose que longtemps dans le passé un programmeur était paresseux ou pas d'y penser, et juste écrit le code C (current_time - file_time) / 86400. C arithmétique entière jette le reste. Les scripts ont commencé en fonction de ce comportement et ont donc été standardisés.

Le comportement spécifié serait également transférable à un système hypothétique qui ne stockait qu'une date de modification (et non une heure). Je ne sais pas si un tel système a existé.

derobert
la source
3
find a clairement été conçu pour effectuer des travaux de nettoyage uniquement.
Kjeld Flarup le
84

L'argument à -mtimeest interprété comme le nombre de jours entiers dans l'âge du fichier. -mtime +nsignifie strictement supérieur à , -mtime -nsignifie strictement inférieur à.

Notez qu'avec Bash, vous pouvez faire le plus intuitif:

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

pour rechercher des fichiers plus anciens et plus récents que 24 heures, respectivement.

(Il est également plus facile de taper un argument fractionnel -mtimeque lorsque vous souhaitez une résolution en heures ou en minutes.)

Evgeni Sergeev
la source
2
Pour répertorier ces fichiers (uniquement normaux) avec des tailles lisibles par l'homme et dans l'ordre chronologique, faites$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Evgeni Sergeev
1
Cela aura également le même effet en ce que ces deux commandes ensemble manqueront toujours les fichiers à l'intérieur de cette fenêtre d'une minute il y a 24 heures.
Octopus
1
$(())est une syntaxe arithmétique de shell simple, elle n’est pas spécifique à Bash, cf. pubs.opengroup.org/onlinepubs/009695399/utilities/…
Josip Rodin
@JosipRodin Non, pas nécessairement vrai! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Etant donné que Bash est un SH "étendu", il prend en charge cette syntaxe, mais pas d’autres shells, par exemple csh / tcsh.
t0r0X
@ t0r0X ce que je voulais dire, c'est que ce n'est pas un bashisme, mais que ça fonctionne en dash et zsh et que tout le reste sert de convention /bin/sh.
Josip Rodin
45

Les périodes fractionnelles de 24 heures sont tronquées! Cela signifie que «find -mtime +1» indique de faire correspondre les fichiers modifiés il y a deux jours ou plus.

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

Ce qui suit ne fonctionne que sur 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
la source
Merci, j'essayais de comprendre pourquoi -mtime X était différent de -mtime + X
Vnge
Je suppose que + X signifie un short pour (X + 1, X + 2, X + 3, ...). :)
Eric Zheng
18

Donc, si un fichier a 1 jour, 23 heures, 59 minutes et 59 secondes, find -mtime +1 ignore tout cela et le traite comme s'il en avait un, 1 heure, 0 minute, 0 minute et 0 secondes?

Oui. Comme man finddit, "toute partie fractionnaire est ignorée". Si vous divisez "1 jour, 23 heures, 59 minutes et 59 secondes" en "24 heures", vous obtiendrez 1,9999, mais la partie .9999 sera alors supprimée et le fichier n'aura plus qu'un seul jour.

Martin von Wittich
la source
18

-mtime Ndésigne les fichiers dont l’âge A en jours satisfait NA < N +1. En d'autres termes, sélectionne les derniers fichiers modifiés entre N et N +1 jours auparavant.-mtime N

-mtime -Ndésigne les fichiers dont l’âge A satisfait à A < N , c’est-à-dire les fichiers modifiés il y a moins de N jours. De manière moins intuitive, les fichiers dont l’âge A satisfait N +1 ≤ A , c’est-à-dire les fichiers modifiés il y a au moins N +1 jours.-mtime +N

Par exemple, -mtime 1sélectionne les fichiers qui ont été modifiés entre 1 et 2 jours. -mtime +1sélectionne les fichiers qui ont été modifiés il y a au moins 2 jours. Pour que les fichiers soient modifiés il y a au moins un jour, utilisez -mtime +0.

La description «a été modifiée pour la dernière fois il y a n * 24 heures» n’est qu’une approximation, et elle n’est pas très claire.

Si vous avez du mal à vous souvenir de ces règles, utilisez plutôt un fichier de référence.

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

(La syntaxe «Il y a 1 jour» nécessite GNU touch.)

Gilles
la source
3
Belle explication, les 3 premiers paragraphes devraient être ajoutés à la documentation de find!
Melebius
4

Utilisez -mmin, -amin, etc. pour obtenir des résultats exacts

Eran Ben-Natan
la source
6
Les -?minarguments fonctionnent exactement comme les -?timearguments sauf avec les minutes au lieu de jours. Ils ne sont pas "exacts" non plus.
Gilles
-2

Si vous voulez des fichiers datant exactement de 48 heures, et non de 2 jours, vous devez ajouter --daystartvotre findcommande. Cela vous aidera.

find . type -f -daystart -mtime +1
Aravind Goud
la source
5
Non, c'est d'abord -daystart(une extension GNU), pas --daystart. Ensuite, il -daystartsuffit de comparer les heures avec le début d'aujourd'hui au lieu de l'heure actuelle. Par conséquent --daystart -mtime +1, les fichiers modifiés plus de 48h / 2 heures avant le début de la journée sont généralement signalés. .
Stéphane Chazelas