bagaimana cara memeriksa bash apakah file dibuat lebih dari x waktu yang lalu?

106

Saya ingin memeriksa di linux bash apakah sebuah file dibuat lebih dari x waktu yang lalu.

katakanlah file tersebut bernama text.txt dan waktunya 2 jam.

 if [ what? ]
 then
     echo "old enough"
 fi
flybywire
sumber

Jawaban:

138

Hanya untuk waktu modifikasi

if test `find "text.txt" -mmin +120`
then
    echo old enough
fi

Anda dapat menggunakan -cminuntuk perubahan atau -aminuntuk waktu akses. Seperti yang ditunjukkan orang lain, saya rasa Anda tidak dapat melacak waktu pembuatan.

kmkaplan
sumber
3
Anda bisa drop 'test' dan backticks. Ini analog dengan 'if (test == true)' vs 'if (test)'
senjata
2
Kamu benar; Saya kira saya berpikir bahwa findmengembalikan bukan nol ketika tidak ada kecocokan yang ditemukan.
senjata
4
Anda dapat melepaskan backticks dan melakukan jika tes $ (temukan text.txt -mmin +120)
tommy.carstensen
1
@BroSlow terlihat lebih baik: tidak ada "lebih dari satu" yang mungkin. Tentu saja, text.txtdianggap bukan direktori.
kmkaplan
2
Saya lebih suka sintaks ini:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe
42

Saya selalu suka menggunakan date -r /the/file +%s untuk menemukan usianya.

Anda juga dapat melakukannya touch --date '2015-10-10 9:55' /tmp/fileuntuk mendapatkan waktu yang sangat terperinci pada tanggal / waktu yang berubah-ubah.

nemik
sumber
Saya mencari hal yang sama hari ini. Terbaik!
Umair A.
Terima kasih. Saya mendapat pertanyaan SO ini karena saya mencari di Google "bagaimana cara mencetak usia file bash." Jadi inilah yang saya cari!
Noah Sussman
5
Terima kasih! dengan satu-satunya peringatan bahwa di atas adalah stempel waktu (bukan usia) tetapi dapat digunakan untuk menghitung usia seperti itu let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [dengan asumsi yang dibuat dan tidak pernah diubah, atau "usia relatif terhadap mod"]
nhed
function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
turiyag
1
@turiyag Catatan wajib yang $[ ], jika tidak usang , paling tidak tua dan kurang portabel , dan $(( ))sebagai gantinya harus digunakan ; dan kutipan balik lebih rapuh daripada $( ); dan juga tanda hubung di nama fungsi mungkin tidak sepenuhnya portabel. Namun, intinya bagus!
michaelb958 - GoFundMonica
23

Menggunakan statuntuk mengetahui tanggal modifikasi terakhir file, dateuntuk mengetahui waktu saat ini dan penggunaan bashisme yang bebas, seseorang dapat melakukan pengujian yang Anda inginkan berdasarkan waktu modifikasi terakhir file 1 .

if [ "$(( $(date +"%s") - $(stat -c "%Y" $somefile) ))" -gt "7200" ]; then
   echo "$somefile is older then 2 hours"
fi

Meskipun kodenya sedikit kurang dapat dibaca daripada findpendekatannya, saya pikir ini adalah pendekatan yang lebih baik daripada menjalankan finduntuk melihat file yang sudah "ditemukan". Selain itu, manipulasi tanggal juga menyenangkan ;-)


  1. Seperti yang dicatat Phil dengan benar, waktu pembuatan tidak direkam, tetapi gunakan %Zsebagai pengganti di %Ybawah ini untuk mendapatkan "waktu perubahan" yang mungkin sesuai dengan keinginan Anda.

[Memperbarui]

Untuk pengguna mac, gunakan stat -f "%m" $somefilesintaks khusus Linux di atas sebagai pengganti

Guss
sumber
Di shell apa tanggal dan stat dibangun? Pesta saya (GNU, 3.2.48) tidak memilikinya.
Ian Clelland
Ups, maaf. stattidak builtin - sangat buruk dari saya, saya akan memperbaikinya.
Guss
1
Solusi @Guss yang tepat adalah memasang coretutils dengan brew. :-)
Erik Johansson
1
@ErikJohansson Saya memilih untuk tidak memerlukan instalasi perangkat lunak tambahan saat menggunakan yang sudah ada berfungsi dengan baik - ini bukan Windows, Anda tahu ;-)
Guss
1
Bagi orang yang ingin menggunakan ini tetapi memodifikasinya, alangkah baiknya mengetahui dengan tepat apa yang dilakukannya: $ (($ (date + "% s") - detik sejak 1970-01-01 00:00:00 UTC (Epoch) $ (stat -c "% Y" $ somefile))) - Waktu modifikasi terakhir sebagai detik sejak Epoch -gt "7200" - memeriksa apakah perbedaannya lebih besar dari x jumlah detik.
devo
16

Waktu pembuatan tidak disimpan.

Apa yang disimpan adalah tiga cap waktu (umumnya, mereka dapat dimatikan pada sistem file tertentu atau dengan opsi sistem file tertentu):

  • Waktu akses terakhir
  • Waktu modifikasi terakhir
  • Waktu perubahan terakhir

a "Perubahan" ke file dihitung sebagai perubahan izin, ganti nama, dll. Sementara modifikasi hanya konten.

Philip Reynolds
sumber
12

Meskipun ctime tidak secara teknis waktu penciptaan, namun seringkali demikian.

Karena ctime tidak terpengaruh oleh perubahan konten file, biasanya hanya diperbarui saat file dibuat. Dan ya - saya dapat mendengar Anda semua berteriak - itu juga diperbarui jika Anda mengubah izin akses atau kepemilikan ... tetapi umumnya itu adalah sesuatu yang dilakukan sekali, biasanya pada saat yang sama Anda meletakkan file di sana.

Secara pribadi saya selalu menggunakan mtime untuk segala hal, dan saya membayangkan itulah yang Anda inginkan. Tapi bagaimanapun ... berikut adalah pengulangan dari pesta "tidak menarik" Guss, dalam fungsi yang mudah digunakan.

#! / bin / bash
function age () {
   nama file lokal = $ 1
   lokal berubah = `stat -c% Y" $ nama file "`
   lokal sekarang = `tanggal +% s`
   lokal berlalu

   let elapsed = sekarang-berubah
   echo $ berlalu
}

file = "/"
echo Umur $ file adalah $ (age "$ file") detik.
Maryam Jeddian
sumber
Ini berguna, tetapi tidak langsung berfungsi untuk OSX karena stat diterapkan secara berbeda di atasnya. Satu-satunya cara yang kompatibel lintas-sistem yang saya temukan adalah dengan menggunakan perl. Skrip harus bekerja di Mac jika Anda mengganti baris yang sesuai dengan ini: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille
1
"Waktu penciptaan" adalah konsep yang sulit dipahami. Apa artinya untuk file yang disalin? Untuk apa file yang dipindahkan? Bagaimana jika itu dipindahkan melintasi batas perangkat (jadi itu dibuat lagi, dalam arti tertentu)? Apa artinya untuk file yang dikemas dan kemudian tidak dikemas? Beberapa jawaban dimungkinkan di sini dan tidak ada konsensus. Menyebutkan waktu memang menyenangkan, tetapi saya tidak akan menempatkannya secara semantik di dekat konsep yang tidak jelas tentang "waktu penciptaan". Terutama karena yang sederhana chmod, diterapkan pada file tersebut, akan membatalkan ide itu. Tapi aku bisa hidup denganmu melakukan itu ;-)
Alfe
@Alfe: Anda melewatkan +%sparuh kedua
Grizly
Usia itu bisa jauh lebih pendek: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (Terima kasih kepada @Grizly untuk koreksinya!)
Alfe
Sebenarnya lebih baik menggunakan waktu akses yang merupakan waktu pembuatan pada semua sistem file yang dipasang dengan noatimeopsi (yang bagus untuk kinerja jadi Anda harus menggunakannya). Jadi gunakan saja, %Xbukan %Y.
Nux
7

Menemukan yang bagus tetapi saya pikir Anda dapat menggunakan cara lain, terutama jika Anda perlu sekarang berapa detik file yang lama

date -d "now - $( stat -c "%Y" $filename ) seconds" +%s

menggunakan tanggal GNU

Vide
sumber
gunakan gstat, "brew install coreutils"
Erik Johansson
3

Pertimbangkan hasil dari alat 'stat':

  File: `infolog.txt'
  Size: 694         Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 11635578    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     fdr)   Gid: ( 1000/     fdr)
Access: 2009-01-01 22:04:15.000000000 -0800
Modify: 2009-01-01 22:05:05.000000000 -0800
Change: 2009-01-01 22:05:05.000000000 -0800

Anda dapat melihat di sini tiga tanggal untuk Mengakses / memodifikasi / mengubah. Tidak ada tanggal dibuat. Anda hanya dapat benar-benar yakin bila konten file telah diubah (kolom "ubah") atau inode-nya diubah (kolom "ubah").

Contoh saat kedua kolom diperbarui:

"Ubah" akan diperbarui jika seseorang menggabungkan informasi tambahan ke akhir file.

"Ubah" akan diperbarui jika seseorang mengubah izin melalui chmod.

fdr
sumber
diberikan, stat dapat memberi tahu Anda informasi yang relevan. Tetapi akan sangat membosankan untuk mengurai untuk mendapatkan yang kita inginkan.
PypeBros
0

saya menggunakan

file_age() {
    local filename=$1
    echo $(( $(date +%s) - $(date -r $filename +%s) ))
}

is_stale() {
    local filename=$1
    local max_minutes=20
    [ $(file_age $filename) -gt $(( $max_minutes*60 )) ]
}

if is_stale /my/file; then
    ...
fi
xpmatteo.dll
sumber