Mengapa menemukan -mtime +1 hanya mengembalikan file yang lebih lama dari 2 hari?

117

Aku berjuang untuk membungkus pikiran saya sekitar mengapa yang findmenafsirkan mengajukan kali modifikasi jalan tersebut. Secara khusus, saya tidak mengerti mengapa -mtime +1file tidak menampilkan kurang dari 48 jam.

Sebagai contoh pengujian, saya membuat tiga file pengujian dengan tanggal modifikasi berbeda:

[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

Saya kemudian menjalankan find dengan -mtime +1switch dan mendapatkan output berikut:

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

Saya kemudian menjalankan find dengan -mmin +1440dan mendapatkan output berikut:

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

Sesuai halaman manual untuk menemukan, saya mengerti bahwa ini adalah perilaku yang diharapkan:

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

Ini masih tidak masuk akal bagi saya. Jadi, jika sebuah file berumur 1 hari, 23 jam, 59 menit, dan 59 detik, find -mtime +1abaikan semua itu dan anggap saja itu seperti 1 hari, 0 jam, 0 menit, dan 0 detik? Dalam hal ini, secara teknis tidak lebih tua dari 1 hari dan diabaikan?

Tidak ... tidak ... menghitung.

Mike B
sumber
7
Pada awalnya itu tampak lucu bagi saya juga, tetapi ketika Anda menganggap bahwa itu mengukur usia file dalam bilangan bulat hari, maka ia melakukan persis apa yang Anda harapkan. Itu tidak akan memberikan file yang sama dengan 1 hari. File yang berumur int (1.99) hari tidak> 1.
Octopus

Jawaban:

87

Yah, jawabannya yang sederhana adalah, saya kira, bahwa implementasi find Anda mengikuti standar POSIX / SuS, yang mengatakan itu harus berperilaku seperti ini. Mengutip dari SUSv4 / IEEE Std 1003.1, 2013 Edition, "find" :

-mtime n
     Primer harus mengevaluasi sebagai benar jika waktu modifikasi file dikurangi
     dari waktu inisialisasi, dibagi dengan 86400 (dengan sisa yang dibuang), adalah n.

(Di tempat lain dalam dokumen itu dijelaskan bahwa nsebenarnya bisa +n, dan makna itu sebagai "lebih besar dari").

Mengapa standar mengatakan itu akan berperilaku dengan cara-baik, aku rasa panjang di masa lalu programmer malas atau tidak berpikir tentang hal itu, dan hanya menulis kode C (current_time - file_time) / 86400. Aritmetika C integer membuang sisanya. Script mulai tergantung pada perilaku itu, dan karenanya distandarisasi.

Perilaku spec'd juga akan portabel untuk sistem hipotetis yang hanya menyimpan tanggal modifikasi (bukan waktu). Saya tidak tahu apakah sistem seperti itu sudah ada.

derobert
sumber
3
find jelas dirancang untuk melakukan pekerjaan pembersihan saja.
Kjeld Flarup
84

Argumen untuk -mtimeditafsirkan sebagai jumlah hari penuh dalam usia file. -mtime +nberarti lebih besar dari , -mtime -nberarti sangat kurang dari.

Perhatikan bahwa dengan Bash, Anda dapat melakukan yang lebih intuitif:

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

untuk menemukan file yang lebih lama dan lebih baru dari 24 jam, masing-masing.

(Ini juga lebih mudah daripada mengetikkan argumen fraksional -mtimeketika Anda ingin resolusi dalam jam atau menit.)

Evgeni Sergeev
sumber
2
Untuk membuat daftar file-file tersebut (hanya reguler) dengan ukuran yang dapat dibaca manusia dan dalam urutan kronologis, lakukan$ find . -type f -mmin -$((60*24)) -exec ls -halt {} +
Evgeni Sergeev
1
Ini juga akan memiliki efek yang sama bahwa kedua perintah tersebut bersama-sama masih akan melewatkan file di dalam jendela satu menit 24 jam yang lalu.
Octopus
1
$(())adalah sintaks aritmatika shell biasa, ini tidak spesifik untuk Bash, lih. pubs.opengroup.org/onlinepubs/009695399/utilities/...
Josip Rodin
@JosipRodin Tidak, belum tentu benar! This chapter describes the syntax of that command language as it is used by the sh utility and [...]. Karena Bash adalah SH "extended", ia mendukung sintaks ini, tetapi beberapa shell lain tidak, misalnya csh / tcsh.
t0r0X
@ t0r0X maksud saya adalah bahwa itu bukan bashism, melainkan bekerja di dash dan zsh dan apa pun berfungsi sebagai konvensional /bin/sh.
Josip Rodin
45

Periode 24 jam pecahan terpotong! Itu berarti “find -mtime +1” mengatakan untuk mencocokkan file yang dimodifikasi dua hari atau lebih yang lalu.

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

Yang berikut ini hanya dapat bekerja pada 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
sumber
Terima kasih, saya mencoba mencari tahu mengapa -mtime X berbeda dari -mtime + X
Vnge
Saya pikir + X berarti celana pendek untuk (X + 1, X + 2, X + 3, ...). :)
Eric Zheng
18

Jadi, jika sebuah file berumur 1 hari, 23 jam, 59 menit, dan 59 detik, temukan -mtime +1 mengabaikan semua itu dan memperlakukannya seperti 1 hari, 0 jam, 0 menit, dan 0 detik?

Iya. Seperti man findkata, "bagian pecahan diabaikan". Jika Anda membagi "1 hari, 23 jam, 59 menit, dan 59 detik" hingga "24 jam", Anda mungkin mendapatkan 1,9999, tetapi bagian .9999 kemudian dilucuti dan tiba-tiba file tersebut hanya berusia 1 hari.

Martin von Wittich
sumber
18

-mtime Nberarti file yang usianya A dalam hari memenuhi NA < N +1. Dengan kata lain, pilih file yang terakhir diubah antara N dan N +1 hari yang lalu.-mtime N

-mtime -Nberarti file yang usianya A memenuhi A < N , yaitu file yang dimodifikasi kurang dari N hari yang lalu. Kurang intuitif, berarti file yang usianya A memenuhi N +1 ≤ A , yaitu file yang diubah setidaknya N +1 hari yang lalu.-mtime +N

Misalnya, -mtime 1memilih file yang dimodifikasi antara 1 dan 2 hari yang lalu. -mtime +1memilih file yang telah diubah setidaknya 2 hari yang lalu. Untuk mendapatkan file yang dimodifikasi setidaknya 1 hari yang lalu, gunakan -mtime +0.

Deskripsi "terakhir diubah n * 24 jam yang lalu" hanya merupakan perkiraan, dan bukan yang sangat jelas.

Jika Anda merasa aturan ini sulit diingat, gunakan file referensi sebagai gantinya.

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

(Sintaks "1 hari yang lalu" memerlukan GNU touch.)

Gilles
sumber
3
Penjelasan yang bagus, 3 paragraf pertama harus ditambahkan ke dokumentasi find!
Melebius
4

Gunakan -mmin, -amin, dll untuk mendapatkan hasil yang tepat

Eran Ben-Natan
sumber
6
The -?minargumen bekerja persis seperti -?timeargumen kecuali dengan menit bukan hari. Mereka juga tidak "tepat".
Gilles
-2

Jika Anda menginginkan file yang berumur 48 jam, bukan 2 hari, maka Anda harus menambahkan perintah --daystartAnda find. Ini akan membantu Anda.

find . type -f -daystart -mtime +1
Aravind Goud
sumber
5
Tidak, pertama itu -daystart(ekstensi GNU), bukan --daystart. Kemudian, -daystarthanya berarti membandingkan waktu dengan awal hari ini daripada waktu saat ini, jadi --daystart -mtime +1akan melaporkan file yang dimodifikasi lebih dari 48 jam / 2 jam sebelum awal hari ini, jadi biasanya file yang dimodifikasi secara kaku sebelum hari sebelum kemarin .
Stéphane Chazelas