bash'da bir dosyanın x zamandan daha önce oluşturulup oluşturulmadığını nasıl kontrol ederim?


106

Linux bash'da bir dosyanın x süreden daha önce oluşturulup oluşturulmadığını kontrol etmek istiyorum.

Diyelim ki dosyanın adı text.txt ve süresi 2 saat.

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

Yanıtlar:


139

Sadece değişiklik zamanı için

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

-cminDeğişim veya -aminerişim süresi için kullanabilirsiniz . Diğerlerinin de belirttiği gibi, oluşturma zamanını izleyebileceğinizi sanmıyorum.


3
'testi' ve geri işaretlerini bırakabilirsiniz. Bu, 'if (test == true)' ve 'if (test)' ile benzerdir
silahlar

2
Haklısın; Sanırım findhiçbir eşleşme bulunmadığında sıfırdan farklı döndü diye düşünüyordum .
guns

4
Geri işaretlerini bırakabilir ve test $ (text.txt bul
-mmin

1
İyi görünür @BroSlow: orada hiçbir "birden fazla" mümkün. Tabii ki, text.txtbir dizin olmadığı varsayılır.
kmkaplan

2
Bu sözdizimini tercih ederim:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe

42

date -r /the/file +%sYaşını bulmak için kullanmayı hep sevmişimdir .

Ayrıca touch --date '2015-10-10 9:55' /tmp/file, gelişigüzel bir tarih / saatte son derece ayrıntılı bir zaman elde etmek için de yapabilirsiniz .


Bugün aynı şeyi arıyordum. En iyi!
Umair A.

Teşekkürler. Bu SO sorusuna geldim çünkü Google'da "file bash yaşının nasıl yazdırılacağını" araştırdım. Demek tam olarak aradığım buydu!
Noah Sussman

5
Teşekkürler! Yukarıdakinin bir zaman damgası (yaş değil) olduğu, ancak yaşı bu şekilde hesaplamak için kullanılabileceğine dair tek uyarı let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) ile [oluşturulmuş ve hiç değiştirilmemiş varsayımıyla veya "
modla ilgili

function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
turiyag

1
@turiyag Zorunlu notu $[ ]değilse olduğunu kaldırılmış , en azından eski ve daha az taşınabilir ve bir kullanmalıdır $(( ))yerine; ve geri alıntılar daha kırılgandır $( ); ve ayrıca işlev adlarındaki kısa çizgiler tam olarak taşınabilir olmayabilir. Yine de özü iyidir!
michaelb958 - GoFundMonica

23

Kullanılması stat, dosyanın son değişiklik tarihini anlamaya dateşimdiki zaman ve bashisms liberal kullanımını anlamaya, bir sen dosyanın son değişiklik zamanına göre istediğiniz testi yapabilirsiniz 1 .

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

Kod findyaklaşıma göre biraz daha az okunabilir olsa da, daha findönce "bulduğunuz" bir dosyaya bakmak için koşmaktan daha iyi bir yaklaşım olduğunu düşünüyorum . Ayrıca tarih manipülasyonu eğlencelidir ;-)


  1. Phil'in doğru bir şekilde belirttiği gibi oluşturma zamanı kaydedilmez, ancak istediğiniz gibi "değişim zamanı" elde etmek için aşağıdaki %Zyerine kullanın %Y.

[Güncelleme]

Mac kullanıcıları için, stat -f "%m" $somefileyukarıdaki Linux'a özgü sözdizimi yerine kullanın


Tarih ve stat hangi kabukta yerleşiktir? Benim bash'ım (GNU, 3.2.48) bunlara sahip değil.
Ian Clelland

Ayy üzgünüm. statyerleşik değil - benim için çok kötü, düzelteceğim.
Guss

1
@Guss doğru çözüm, brew ile coretutils kurmaktır. :-)
Erik Johansson

1
@ErikJohansson Mevcut olanı kullanırken ek yazılım yüklemesine ihtiyaç duymamayı tercih ediyorum - bu Windows değil, biliyorsunuz ;-)
Guss

1
Bunu kullanmak isteyen ancak değiştirmek isteyenler için, tam olarak ne yaptığını bilmek iyi olacaktır: $ (($ (tarih + "% s") - 1970-01-01 00:00:00 UTC'den bu yana saniye (Epoch) $ (stat -c "% Y" $ somefile))) - Epoch -gt "7200" ten bu yana geçen saniye olarak yapılan son değişiklik zamanı - farkın x saniye sayısından büyük olup olmadığını kontrol eder.
devo

16

Oluşturma zamanı kaydedilmez.

Depolananlar üç zaman damgasıdır (genellikle, belirli dosya sistemlerinde veya belirli dosya sistemi seçenekleriyle kapatılabilirler):

  • Son erişim zamanı
  • Son değişiklik zamanı
  • Son değişiklik zamanı

Dosyadaki bir "Değişiklik", izin değişiklikleri, yeniden adlandırma vb. olarak sayılır. Değişiklik yalnızca içeriktir.


12

Ctime teknik olarak yaratılış zamanı olmasa da , çoğu zaman öyledir.

Ctime, dosyanın içeriğindeki değişikliklerden etkilenmediğinden, genellikle yalnızca dosya oluşturulduğunda güncellenir. Ve evet - hepinizin çığlık attığını duyabiliyorum - erişim izinlerini veya sahipliğini değiştirirseniz de güncellenir ... ama genellikle bu bir kez yapılır, genellikle dosyayı oraya koyarken aynı anda yapılır.

Şahsen ben her zaman her şey için mtime kullanırım ve senin istediğinin bu olduğunu düşünüyorum. Ama her neyse ... işte Guss'un "çekici olmayan" bash'ının kullanımı kolay bir işlevde yeniden yayınlanması.

#! / bin / bash
function yaş () {
   yerel dosya adı = 1 $
   yerel değiştirildi = `stat -c% Y" $ dosya adı "`
   şimdi yerel = `tarih +% s`
   yerel geçen

   let geçen = şimdi-değiştirildi
   echo $ geçti
}

file = "/"
echo $ file'ın yaşı $ (yaş "$ dosya") saniyedir.

Bu yararlıydı, ancak OSX için hemen işe yaramadı çünkü stat farklı şekilde uygulanıyor. Bulduğum tek çapraz sistem uyumlu yol perl kullanmaktı. Karşılık gelen satırı şu satırla değiştirirseniz, komut dosyası Mac'lerde çalışmalıdır: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille

1
"Yaratılış zamanı" anlaşılması zor bir kavramdır. Kopyalanan bir dosya için bu ne anlama geliyor? Taşınan dosya için ne var? Ya bir cihaz sınırından geçtiyse (yani bir anlamda yeniden yaratılmışsa)? Paketlenmiş ve daha sonra paketlenmemiş bir dosya için bu ne anlama geliyor? Burada birkaç cevap mümkündür ve fikir birliği yoktur. Yine de ctime'dan bahsetmek güzel, ama anlamsal olarak belirsiz bir "yaratma zamanı" kavramına yaklaşmam. Özellikle basit bir chmoddosya üzerine uygulandığı için bu fikri geçersiz kılacaktır. Ama seninle bunu yaparak yaşayabilirim ;-)
Alfe

@Alfe: +%sİkinci yarıdaki eksik
Grizly

Bu yaş yolu daha kısa olabilir: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (düzeltme @Grizly teşekkürler!)
Alfe

Aslında, noatimeseçenekle bağlanan tüm dosya sistemlerinde bir oluşturma zamanı olan erişim zamanını kullanmak daha iyidir (bu performans için iyidir, bu yüzden onu kullanmalısınız). Bu yüzden %Xyerine kullanın %Y.
Nux

7

Bulmak iyi ama bence başka bir yol da kullanabilirsiniz, özellikle şu anda dosya kaç saniyedir gerekiyorsa

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

GNU tarihini kullanarak


gstat kullanın, "brew install coreutils"
Erik Johansson

3

'İstatistik' aracının sonucunu düşünün:

  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

Burada Erişim / değiştirme / değiştirme için üç tarihi görebilirsiniz. Oluşturma tarihi yok. Yalnızca dosya içeriğinin ne zaman değiştirildiğinden ("değiştir" alanı) veya inode'unun değiştirildiğinden ("değiştir" alanı) gerçekten emin olabilirsiniz.

Her iki alanın ne zaman güncellendiğine ilişkin örnekler:

Birisi dosyanın sonuna fazladan bilgi eklerse "Değiştir" güncellenecektir.

Birisi chmod aracılığıyla izinleri değiştirirse "Değiştir" güncellenecektir.


verildi, stat size ilgili bilgileri söyleyebilir. Ancak istediğimizi elde etmek için ayrıştırmak oldukça sıkıcı olacaktır.
PypeBros

0

kullanırım

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.