/ / Linux-Datei Erstellung Timestamp Race-Bedingungen - Linux, Suche, Zeitstempel

Zeitstempelbedingungen für die Erstellung von Linux-Dateien - linux, find, timestamp

Ich versuche zu tun, was ich denke, ist eine einfache Sacheunter Linux. Ich habe ein Bash-Skript, das verschiedene Testprogramme ausführt, und ich möchte feststellen, welche Dateien im aktuellen Verzeichnis von den Testprogrammen erstellt wurden. Also mache ich so etwas:

Touch Timestamp-Datei Führen Sie den Test aus finde -newer timestamp-file -type f> list-of-files rm -f Zeitstempel-Datei

Stellt sich heraus, dass die Granularität von find -newer schlecht ist, was normalerweise passiert, ist, dass einige Dateien, die vom Testprogramm generiert wurden, als ÄLTER angezeigt werden als die Timestamp-Datei. Also habe ich folgendes versucht:

ls -tr1 | sed "1, / Zeitstempel-Datei / d"

um die gleiche Liste zu erzeugen. Dies gewöhnlich funktioniert, aber nicht immer. Ich habe immer noch die Situation, dass Dateien, die durch den Test generiert wurden, älter als die Zeitstempeldatei sind.

Vielen Dank!

P.S. Ich kann dies auf eine andere Art und Weise erreichen, indem ich zwei Schnappschüsse des Verzeichnisses mache, eines vor dem Testprogramm und dann eines danach, und sie vergleichen. Alle Dateien in der zweiten Liste, die nicht in der ersten Liste enthalten sind, müssen vom Testprogramm erstellt worden sein (ich kümmere mich nicht um Hintergrundjobs oder andere Benutzer, die in das Verzeichnis schreiben). Aber diese Methode ist nicht das, was ich möchte Datei wurde nicht entfernt, bevor der Test ausgeführt wurde (sie sollten es sein, aber in einigen Fällen ist das nicht der Fall), diese Methode sagt, dass sie nicht vom Testprogramm erstellt wurde, weil sie sich vor dem Testprogramm befand wurde ausgeführt.

Antworten:

1 für die Antwort № 1

Nimm die Dateinamen aller Dateien vor dem Lauf, aber schließe ihre Zeitstempel ein:

find -printf "%p %T@n" | sort > file1

Wenn Sie diese Suchoption nicht zur Verfügung haben, können Sie stat auch für diesen Job verwenden:

find -print0 | xargs -0 stat -c "%n %Y" | sort > file1

</ sub>

Und nach dem Lauf nach file2. Dann benutze

comm -1 -3 file1 file2

Und es wird Ihnen die einzigartigen Linien zeigen file2, die neue Dateien sein müssen, wenn ich mich nicht irre. Wenn sie vorher existierten, wird sich ihre Modifikationszeit geändert haben, was von der %T@ dingy (Ausdruck der Anzahl der Sekunden seit 1970):

[js @ HOST2 cpp] $ find -printf "% p% T @ n" | sortieren>Datei1 [js @ HOST2 cpp] $ echofoo> bar [js @ HOST2 cpp] $ echofoo> baz [js @ HOST2 cpp] $ find -printf "% p% T @ n" | Sortieren> Datei2 [js @ HOST2 cpp] $ Komm -1 -3 Datei1 Datei2 . 1230947309,0000000000 ./bar 1230947308.0000000000 ./baz 1230947309.0000000000 ./file2 1230947315.0000000000 [js @ HOST2 cpp] $ find -printf "% p% T @ n" | Sortieren> Datei1 [js @ HOST2 cpp] $ echo lol> bar [js @ HOST2 cpp] $ find -printf "% p% T @ n" | Sortieren> Datei2 [js @ HOST2 cpp] $ Komm -1 -3 Datei1 Datei2 ./bar 1230947359.0000000000 ./file2 1230947362.0000000000 [js @ HOST2 cpp] $ `

3 für die Antwort № 2

Sie können Touch tatsächlich verwenden, um die Zeitstempel aller aktuellen Dateien in dem Verzeichnis zu weit in der Vergangenheit zu erzwingen, wie beispielsweise:

touch -t 200801010000.00 *

Wenn Sie dies tun, bevor Sie Ihren Test ausführen, sollte mehr als genug Zeit für "find -newer"Um es aufzuheben. Wenn die Granularität zwei Minuten betrug, könnten Sie alle aktuellen Dateien auf zehn Minuten setzen, die Zeitstempel-Datei auf 5 Minuten, dann führen Sie Ihren Test aus.

So wird dein Skript:

touch -t (current time - 10 minutes) *
touch -t (current time -  5 minutes) timestamp-file
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file

Angenommen, Sie haben eine ordentliche Installation von Perl, können Sie Folgendes tun, um vor 5 Minuten (oder -600 für 10 Minuten) im richtigen Format für "date -t":

use Date::Manip;
print UnixDate(DateCalc(ParseDateString("now"),"-300"),"%Y%m%d%H%M.%S") . "n";

Wenn Sie aus irgendeinem Grund die Zeitstempel nicht ändern dürfen, verwenden Sie:

sleep 300
touch timestamp-file
sleep 300
run the test
find -newer timestamp-file -type f > list-of-files
rm -f timestamp-file

Das hat die gleiche Wirkung, aber Sie haben zehn Minuten Zeit, um einen Kaffee zu trinken (oder Ihr Gift der Wahl, wenn Sie kein Kaffeetrinker sind).


2 für die Antwort № 3

Wenn Sie überlegen, wie find(1) Es ist klar, warum dies manchmal nicht so funktioniert, wie Sie es erwarten. Hier ist ein Tipp:

  $ touch timestamp ; touch newer ; find . -newer timestamp
$ rm timestamp newer
$ touch timestamp ; sleep 1 ; touch newer ; find . -newer timestamp
.
./newer
$

find(1) ruft die Werte für die Datei mtime / ctime / atime mit dem Systemaufruf ab stat(2). Hier sind die Elemente von struct stat von <sys/stat.h> (Linux):

  time_t    st_atime;   /* time of last access */
time_t    st_mtime;   /* time of last modification */
time_t    st_ctime;   /* time of last status change */

Unter Linux (und allgemein bei Unices) time_t ist eine ganze Zahl, die "Sekunden ab Anfang 1970" darstellt. Daher die feinste Granularität, die -newer kann verstehen, ist nur eine Sekunde.


0 für die Antwort № 4

Warum nicht ein temporäres Verzeichnis erstellen, in demdie Tests durchführen? Verwenden Sie einen zeitstempelbasierten Namen im Verzeichnis, um zu verfolgen, welche Ergebnisse wann aufgetreten sind, und löschen Sie einfach das gesamte Verzeichnis, wenn Sie fertig sind.