Wie überprüfe ich in Bash, ob eine Datei vor mehr als x Mal erstellt wurde?


106

Ich möchte in Linux Bash überprüfen, ob eine Datei vor mehr als x Zeit erstellt wurde.

Angenommen, die Datei heißt text.txt und die Zeit beträgt 2 Stunden.

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

Antworten:


138

Nur zur Änderungszeit

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

Sie können -cminfür Änderungen oder -aminfür die Zugriffszeit verwenden. Wie andere sagten, glaube ich nicht, dass Sie die Erstellungszeit verfolgen können.


3
Sie können 'Test' und die Backticks löschen. Dies ist analog zu 'if (test == true)' vs 'if (test)'
Waffen

2
Du hast Recht; Ich denke, ich dachte, dass findnicht Null zurückgegeben wird, wenn keine Übereinstimmungen gefunden werden.
Waffen

4
Sie können die Backticks löschen und tun, wenn test $ (find text.txt -mmin +120)
tommy.carstensen

1
@BroSlow sieht besser aus: Es ist nicht "mehr als eins" möglich. Natürlich text.txtwird davon ausgegangen, dass es sich nicht um ein Verzeichnis handelt.
kmkaplan

2
Ich bevorzuge diese Syntax:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe

42

Ich habe es immer gemocht date -r /the/file +%s, sein Alter zu finden.

Sie können auch touch --date '2015-10-10 9:55' /tmp/fileeine extrem feinkörnige Zeit an einem beliebigen Datum / einer beliebigen Uhrzeit ermitteln.


Ich habe heute das Gleiche gesucht. Beste!
Umair A.

Vielen Dank. Ich bin auf diese SO-Frage gestoßen, weil ich gegoogelt habe, "wie man das Alter der Datei-Bash druckt". Genau das habe ich gesucht!
Noah Sussman

5
Vielen Dank! mit der einzigen Einschränkung, dass das oben Genannte ein Zeitstempel ist (kein Alter), aber verwendet werden kann, um das Alter wie let AGE=$(($(date +%s)-$(date -r /path/to/file +%s)))
folgt zu berechnen

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

1
@turiyag Obligatorische Anmerkung, $[ ]die, wenn nicht veraltet , mindestens alt und weniger tragbar ist und $(( ))stattdessen verwendet werden sollte; und Backquotes sind zerbrechlicher als $( ); Außerdem können Bindestriche in Funktionsnamen möglicherweise nicht vollständig portierbar sein. Das Wesentliche ist jedoch gut!
michaelb958 - GoFundMonica

23

Mit dem stat, um das letzte Änderungsdatum der Datei dateherauszufinden, um die aktuelle Zeit und eine großzügige Verwendung von Bashismen herauszufinden, können Sie den gewünschten Test basierend auf der letzten Änderungszeit der Datei durchführen 1 .

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

Der Code ist zwar etwas weniger lesbar als der findAnsatz, aber ich denke, er ist besser als das Ausführen findeiner Datei, die Sie bereits "gefunden" haben. Auch Datumsmanipulation macht Spaß ;-)


  1. Wie Phil richtig bemerkte, wird die Erstellungszeit nicht aufgezeichnet, sondern %Zanstelle von %Yunten verwendet, um die "Änderungszeit" zu erhalten, die möglicherweise Ihren Wünschen entspricht.

[Aktualisieren]

Verwenden Sie für Mac-Benutzer stat -f "%m" $somefileanstelle der oben angegebenen Linux-spezifischen Syntax


In welche Shell sind Datum und Statistik eingebaut? Meine Bash (GNU, 3.2.48) hat sie nicht.
Ian Clelland

ups, tut mir Leid. statist nicht eingebaut - sehr schlecht von mir, werde ich reparieren.
Guss

1
@Guss richtige Lösung ist, Coretutils mit Gebräu zu installieren. :-)
Erik Johansson

1
@ErikJohansson Ich bevorzuge es, keine zusätzliche Software zu installieren, wenn die vorhandene verwendet wird. Das funktioniert einwandfrei - das ist nicht Windows, weißt du ;-)
Guss

1
Für Leute, die dies verwenden, aber ändern möchten, ist es gut, genau zu wissen, was es tut: $ (($ (Datum + "% s") - Sekunden seit 1970-01-01 00:00:00 UTC (Epoche) $ (stat -c "% Y" $ somefile))) - Zeitpunkt der letzten Änderung als Sekunden seit Epoche -gt "7200" - prüft, ob die Differenz größer als x Sekunden ist.
Devo

16

Die Erstellungszeit wird nicht gespeichert.

Was gespeichert werden, sind drei Zeitstempel (im Allgemeinen können sie auf bestimmten Dateisystemen oder durch bestimmte Dateisystemoptionen deaktiviert werden):

  • Letzte Zugriffszeit
  • Letzte Änderungszeit
  • Letzte Änderungszeit

Eine "Änderung" der Datei wird als Berechtigungsänderung, Umbenennung usw. gezählt, während die Änderung nur Inhalt ist.


12

Obwohl ctime technisch gesehen nicht die Zeit der Erstellung ist, ist es dies ziemlich oft.

Da ctime nicht von Änderungen am Inhalt der Datei betroffen ist, wird es normalerweise nur aktualisiert, wenn die Datei erstellt wird. Und ja - ich kann Sie alle schreien hören - es wird auch aktualisiert, wenn Sie die Zugriffsberechtigungen oder den Besitz ändern ... aber im Allgemeinen geschieht dies einmal, normalerweise zur gleichen Zeit, zu der Sie die Datei dort ablegen.

Persönlich benutze ich mtime immer für alles und ich stelle mir vor, dass Sie das wollen. Aber trotzdem ... hier ist eine Wiederholung von Guss '"unattraktivem" Bash in einer einfach zu bedienenden Funktion.

#! / bin / bash
Funktion age () {
   lokaler Dateiname = $ 1
   lokal geändert = `stat -c% Y" $ Dateiname "`
   lokal jetzt = `Datum +% s`
   lokal verstrichen

   verstrichen lassen = jetzt geändert
   Echo $ verstrichen
}}

file = "/"
echo Das Alter von $ file beträgt $ (Alter "$ file") Sekunden.

Dies war nützlich, funktionierte jedoch unter OSX nicht sofort, da stat darauf anders implementiert ist. Die einzige systemübergreifende Methode, die ich gefunden habe, war die Verwendung von Perl. Das Skript sollte auf Macs funktionieren, wenn Sie die entsprechende Zeile durch folgende ersetzen: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille

1
"Schöpfungszeit" ist ein Konzept, das schwer zu verstehen ist. Was bedeutet das für eine kopierte Datei? Was ist mit einer verschobenen Datei? Was ist, wenn es über einen Geräterand verschoben wurde (so dass es gewissermaßen neu erstellt wurde)? Was bedeutet das für eine gepackte und später entpackte Datei? Hier sind mehrere Antworten möglich und es besteht kein Konsens. Die ctime zu erwähnen ist zwar nett, aber ich würde es nicht semantisch in die Nähe des vagen Konzepts einer "Schöpfungszeit" bringen. Zumal ein einfaches chmod, auf die Datei angewendetes Element diese Idee zunichte macht. Aber ich kann damit leben , dass du das tust ;-)
Alfe

@ Alfe: Sie vermissen die +%saus der zweiten Hälfte
Grizly

Dieses Alter kann viel kürzer sein: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (Danke an @Grizly für die Korrektur!)
Alfe

Tatsächlich ist es besser, die Zugriffszeit zu verwenden, die eine Erstellungszeit für alle mit noatimeOption bereitgestellten Dateisysteme ist (was für die Leistung gut ist, daher sollten Sie sie verwenden). Also einfach %Xanstelle von verwenden %Y.
Nux

7

Das Finden ist gut, aber ich denke, Sie können es auch anders verwenden, besonders wenn Sie jetzt wissen müssen, wie viele Sekunden die Datei alt ist

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

mit GNU Datum


Verwenden Sie gstat, "Brew Install Coreutils"
Erik Johansson

3

Betrachten Sie das Ergebnis des Tools '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

Sie können hier die drei Daten für Zugriff / Ändern / Ändern sehen. Es gibt kein Erstellungsdatum. Sie können nur wirklich sicher sein, wann der Dateiinhalt geändert wurde (das Feld "Ändern") oder der Inode geändert wurde (das Feld "Ändern").

Beispiele dafür, wann beide Felder aktualisiert werden:

"Ändern" wird aktualisiert, wenn jemand zusätzliche Informationen an das Ende der Datei angekettet hat.

"Ändern" wird aktualisiert, wenn jemand die Berechtigungen über chmod geändert hat.


Zugegeben, stat kann Ihnen relevante Informationen mitteilen. Aber es wird ziemlich mühsam sein, zu analysieren, um das zu bekommen, was wir wollen.
PypeBros

0

ich benutze

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.