Por que encontrar -mtime +1 retorna apenas arquivos com mais de 2 dias?

117

Estou lutando para entender por que a findmodificação dos arquivos de interpretação interpreta o tempo como acontece. Especificamente, não entendo por que o -mtime +1arquivo não mostra arquivos com menos de 48 horas.

Como exemplo de teste, criei três arquivos de teste com diferentes datas de modificação:

[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

Em seguida, corri find com o -mtime +1switch e obtive a seguinte saída:

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

Em seguida, executei o find com o -mmin +1440e obtive a seguinte saída:

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

De acordo com a página de manual do find, entendo que este é um comportamento 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.

Isso ainda não faz sentido para mim. Portanto, se um arquivo tiver 1 dia, 23 horas, 59 minutos e 59 segundos, find -mtime +1ignora tudo isso e o trata como se tivesse 1 dia, 0 horas, 0 minutos e 0 segundos? Nesse caso, não é tecnicamente mais antigo que 1 dia e ignorado?

Não computa.

Mike B
fonte
7
No começo, também me pareceu engraçado, mas quando você considera que mede a idade de um arquivo em dias inteiros, ele faz exatamente o que você esperaria. Não fornecerá arquivos iguais a 1 dia de idade. Um arquivo com int (1.99) dias de idade não é> 1. #
Octopus

Respostas:

87

Bem, a resposta simples é, eu acho, que sua implementação de localização está seguindo o padrão POSIX / SuS, que diz que deve se comportar dessa maneira. Citando no SUSv4 / IEEE Std 1003.1, edição de 2013, "find" :

-mtime n
     O primário avaliará como verdadeiro se o tempo de modificação do arquivo subtraído
     do tempo de inicialização, dividido por 86400 (com qualquer restante descartado), for n.

(Em outro lugar desse documento, ele explica que npode realmente ser +n, e o significado disso como "maior que").

Quanto ao porquê da norma diz que deve se comportar dessa forma, bem, eu acho muito tempo no passado um programador era preguiçoso ou não pensar nisso, e apenas escreveu o código C (current_time - file_time) / 86400. A aritmética de número inteiro C descarta o restante. Os scripts começaram dependendo desse comportamento e, portanto, foram padronizados.

O comportamento especificado também seria portável para um sistema hipotético que armazenava apenas uma data de modificação (não hora). Não sei se esse sistema existe.

derobert
fonte
3
O find foi claramente projetado para fazer apenas trabalhos de limpeza.
precisa saber é o seguinte
84

O argumento para -mtimeé interpretado como o número de dias inteiros na idade do arquivo. -mtime +nsignifica estritamente maior que , -mtime -nsignifica estritamente menor que.

Observe que, com o Bash, você pode fazer o mais intuitivo:

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

para encontrar arquivos mais antigos e mais recentes que 24 horas, respectivamente.

(Também é mais fácil do que digitar um argumento fracionário -mtimepara quando você deseja resolução em horas ou minutos.)

Evgeni Sergeev
fonte
2
Para listar esses arquivos (apenas regulares) com tamanhos legíveis por humanos e em ordem cronológica, faça$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Evgeni Sergeev
11
Isso também terá o mesmo efeito, pois os dois comandos juntos ainda perderão os arquivos nessa janela de um minuto, 24 horas atrás.
Oct
11
$(())é uma sintaxe aritmética de casca simples, não é específica para o Bash, cf. pubs.opengroup.org/onlinepubs/009695399/utilities/…
Josip Rodin
@JosipRodin Não, não necessariamente verdade! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Como o Bash é um SH "estendido", ele suporta essa sintaxe, mas alguns outros shells não, por exemplo, csh / tcsh.
T0r0X
@ t0r0X meu argumento é que não é um basismo, mas funciona em dash e zsh e o que mais serve como convencional /bin/sh.
precisa saber é o seguinte
45

Períodos fracionários de 24 horas são truncados! Isso significa que "find -m +1" diz corresponder aos arquivos modificados há dois ou mais dias.

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

O seguinte pode funcionar apenas no 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
fonte
Obrigado, eu estava tentando descobrir por que -mtime X era diferente do que -mtime + X
Vnge
Eu acho que + X significa shorts para (X + 1, X + 2, X + 3, ...). :)
Eric Zheng
18

Portanto, se um arquivo tiver 1 dia, 23 horas, 59 minutos e 59 segundos, encontrar -mtime +1 ignora tudo isso e o trata como se tivesse 1 dia, 0 horas, 0 minutos e 0 segundos?

Sim. Como man finddiz, "qualquer parte fracionária é ignorada". Se você dividir "1 dia, 23 horas, 59 minutos e 59 segundos" por "24 horas", poderá obter 1,9999, mas a parte .9999 será removida e, de repente, o arquivo terá apenas 1 dia.

Martin von Wittich
fonte
18

-mtime Nsignifica arquivos cuja idade A em dias satisfaz NA < N +1. Em outras palavras, seleciona arquivos que foram modificados pela última vez entre N e N +1 dias atrás.-mtime N

-mtime -Nsignifica arquivos cuja idade A satisfaz A < N , ou seja, arquivos modificados há menos de N dias atrás. Menos intuitivamente, significa arquivos cuja idade A satisfaz N +1 ≤ A , ou seja, arquivos modificados há pelo menos N +1 dias atrás.-mtime +N

Por exemplo, -mtime 1seleciona arquivos que foram modificados entre 1 e 2 dias atrás. -mtime +1seleciona arquivos que foram modificados há pelo menos 2 dias atrás. Para modificar os arquivos há pelo menos 1 dia, use -mtime +0.

A descrição "foi modificada pela última vez * há 24 horas" é apenas uma aproximação e não muito clara.

Se você achar essas regras difíceis de lembrar, use um arquivo de referência.

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

(A sintaxe "1 dia atrás" requer GNU touch.)

Gilles
fonte
3
Boa explicação, os 3 primeiros parágrafos devem ser adicionados à documentação do find!
Melebius
4

Use -mmin, -amin, etc, para obter resultados exatos

Eran Ben-Natan
fonte
6
Os -?minargumentos funcionam exatamente como os -?timeargumentos, exceto com minutos em vez de dias. Eles também não são "exatos".
Gilles
-2

Se você deseja exatamente arquivos com 48 horas de duração, e não 2 dias, adicione --daystartseu findcomando. Isso irá ajudá-lo.

find . type -f -daystart -mtime +1
Aravind Goud
fonte
5
Não, primeiro é -daystart(uma extensão GNU), não --daystart. Então, -daystartapenas significa comparar os horários com o início de hoje, e não com o horário atual, para --daystart -mtime +1reportar arquivos que foram modificados mais de 48h / 2 horas antes do início de hoje, portanto, geralmente arquivos que foram modificados rapidamente antes de ontem .
Stéphane Chazelas