Da Sie die stat
(ähnliche Funktionalität, aber unterschiedliches Ausgabeformat für BSDs und GNU) verwenden, können Sie auch das test
Dienstprogramm verwenden, das diesen Vergleich direkt durchführt:
FILE1 -nt FILE2
FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2
FILE1 is older than FILE2
In Ihrem Beispiel
if [ "$source_file" -nt "$target_file" ]
then
printf '%s\n' "$source_file is newer than $target_file"
fi
Die Funktion ist in POSIX nicht verfügbar (siehe Dokumentation zutest
). Dies enthält folgende Gründe:
Einige zusätzliche Vorwahlen, die neu erfunden wurden oder aus der KornShell stammen, wurden in einem frühen Vorschlag als Teil des bedingten Befehls ([[]]) veröffentlicht: s1 >
s2, s1 <
s2, str = Muster, str! = Muster, f1 -nt
f2, f1 -ot
f2 und f1 -ef f2. Sie wurden nicht in das Testdienstprogramm übertragen, als der bedingte Befehl aus der Shell entfernt wurde, da sie nicht in das Testdienstprogramm aufgenommen wurden, das in historischen Implementierungen des Dienstprogramms sh integriert ist.
Dies könnte sich jedoch in Zukunft ändern, da die Funktion weitgehend unterstützt wird.
Beachten Sie, dass bei Operanden als Symlinks die Änderungszeit des Ziels des Symlinks berücksichtigt wird (was im Allgemeinen gewünscht wird, verwenden Sie find -newer
stattdessen, wenn nicht). Wenn Symlinks nicht aufgelöst werden können, das Verhalten zwischen Implementierungen (einige betrachten eine vorhandene Datei als immer neuer als eine, die nicht aufgelöst werden kann, andere melden immer false, wenn einer der Operanden nicht aufgelöst werden kann).
Beachten Sie auch , dass nicht alle Implementierungen unterstützen Unter zweiter Granularität ( bash
s test
/ [
builtin ab Version 4.4 noch nicht zum Beispiel GNU test
und die test
builtin von zsh
oder zu ksh93
tun, zumindest auf GNU / Linux).
Als Referenz:
- Für die GNU
test
Utility - Implementierung (obwohl beachten Sie, dass Ihre Shell, wenn fish
oder Bourne-like, wird auch eine haben test
/ [
builtin , dass es in der Regel Schatten, verwenden env test
statt test
zu Bypass - it), get_mtime in test.c liest struct timespec
, und
- Option
-nt
verwendet diese Daten
struct timespec
, was möglicherweise feinkörniger ist (nicht alle Dateisysteme unterstützen Zeitstempel unter einer Sekunde, aber Sie werden wahrscheinlich das bekommen, was Sie wollten ...)Beim Testen auf diesem Linux-System. Die übliche Methode zum Testen der Dateizeiten ist die Shell:
Scheint mit Sekunden zu arbeiten. Dadurch, dass die Dateien mit einem Zeitunterschied von weniger als einer Sekunde berührt werden, wird dieser Unterschied nicht erkannt:
So bestätigen Sie das Problem (Zeit nach dem Punkt ist Nanosekunden):
Das
file1
ist (etwas) neuer alsfile2
.Das Problem besteht nun darin, den Zeitwert korrekt zu verarbeiten.
Eine Lösung besteht darin, eine formatierte Ausgabe von ls zu verwenden:
Extrahieren der Zeit auf zwei Variablen (ohne Punkt):
Und vergleichen Sie die Zeiten (Zeiten mit Nanosekunden passen kaum in einen 64-Bit-Wert. Wenn Ihr System kein 64-Bit verwendet, schlägt dieser Vergleich fehl):
Das zeigt, dass
file1
das neuer ist alsfile2
Wenn
ls
das erforderliche Format nicht vorhanden ist, können Sie stat ausprobieren.Wenn die Ausgabe Nanosekunden anzeigt, benötigen wir das Datum, um die Uhrzeit zu analysieren (und zu formatieren).
Der Rest ist der gleiche. Ordnen Sie die Ergebnisse von Datei1 und Datei2 zwei Variablen zu und vergleichen Sie sie numerisch.
quelle
date -r
ist wahrscheinlich eine bessere Option, und es scheint x-Plattform zu seinWenn Sie bereit sind, nicht eingebettetes Linux anzunehmen, können Sie den
test
externen Befehl verwenden, der Teil von GNU coreutils ist. (test
ist ein anderer Name für[
und ist in den meisten Muscheln eingebaut). Es hat eine Granose von Nanosekunden (bis zu der vom Dateisystem angegebenen Genauigkeit).Der
-nt
Operator wird nicht von POSIX definiert, ist jedoch in vielen Implementierungen vorhanden, einschließlich dash, bash, pdksh, mksh, ATT ksh, zsh, GNU coreutilstest
und BusyBox. Viele Implementierungen (dash, bash, pdksh, mksh, BusyBox - getestet auf Debian jessie) unterstützen jedoch nur eine Granularität von 1 Sekunde.Es wäre jedoch eine bessere Idee, Tools zu verwenden, die für diesen Job vorgesehen sind, z. B. make . Das Ausführen eines Befehls nur, wenn eine bestimmte Datei neuer als eine andere Datei ist, ist der springende Punkt. Mit dem folgenden Inhalt in einer Datei namens
Makefile
(beachten Sie, dass Sie vor jeder Befehlszeile ein Tabulatorzeichen benötigen).Ausführen
make target
, um die Befehle auszuführen, die es generieren. Wenntarget
vorhanden und neuer alssource
, werden die Befehle nicht ausgeführt. Weitere Informationen finden Sie in der Dokumentation zu make.quelle
/usr/bin/test
und Shell-Builtinstest
implementieren größtenteils dieselbe Funktionalität, es kann jedoch geringfügige Unterschiede geben, und die Unterstützung der Auflösung von Zeitstempeln im Subsekundenbereich ist einer dieser geringfügigen Unterschiede.Das GNU-Datum kann die mtime einer Datei so formatieren, dass sie die Nanosekunden seit der Epoche ist:
Diese Zahlen sind vergleichbar mit test oder '['. Es funktioniert sogar mit Bash v3.00 auf einem i386 (32-Bit) -System (ca. 2008).
quelle
date -r
Option scheint zu funktionieren, ich denke, das ist das gleiche wiedate--reference
POSIXly würden Sie verwenden
find
:Bei Symlinks vergleicht dies die Zeit der Symlinks selbst. Fügen Sie die Option
-H
oder hinzu, um die Ziele der Symlinks zu vergleichen-L
.Dies setzt voraus, dass
$source_file
es nicht mit-
einem derfind
Prädikate beginnt und ansonsten nicht diesem entspricht . Wenn Sie mit beliebigen Dateinamen umgehen müssen, müssen Sie zunächst folgende Schritte ausführen:GNU- und FreeBSD-
find
Implementierungen unterstützen mindestens eine Granularität von weniger als einer Sekunde. AFAICT, macos scheint nicht einmal Informationen im Subsekundenbereich in den Dateiattributen des HFS + -Dateisystems zu speichern.quelle
Unter OSX und Linux
date -r
scheint es gut zu funktionieren, ich benutzedate -r "$file" +%s
, um die Änderungszeit in Sekunden seit der Epoche wie folgt zu erhalten:Dadurch wird überprüft, ob die Änderungszeit in Sekunden für foobar.txt vor 55 Sekunden liegt.
Die Manpage mit der Option -r: http://man7.org/linux/man-pages/man1/date.1.html
quelle