Frage

Ich versuche, zu tun, was ich denke, eine einfache Sache unter Linux. Ich habe einen Bash-Skript, die verschiedene Testprogramme ausgeführt wird, und ich möchte, um zu bestimmen, welche Dateien im aktuellen Verzeichnis durch die Testprogramme erstellt wurden. Also habe ich so etwas wie dies tue:

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

Schaltet die Granularität des Fund -newer aus schlecht ist, so typisch, was passiert, ist, dass einige Dateien, die von dem Testprogramm generiert wurden, zeigen sich als älter als die Zeitstempel-Datei. Also habe ich versucht, dies:

ls -tr1 | sed '1,/timestamp-file/d'

die gleiche Liste zu erzeugen. Diese in der Regel funktioniert, aber nicht immer. Ich immer noch mit der Situation am Ende, wo die Dateien, die durch den Test als älter als die Zeitstempel-Datei auftauchen generiert wurden.

Danke!

P. S. Ich kann, indem man zwei Schnappschüsse des Verzeichnisses dies eine andere Art und Weise erreichen, ein vor dem Testprogramm läuft, und dann eine nach und vergleichen sie. Alle Dateien in der zweiten Liste, die nicht in dem ersten ist, müssen durch das Testprogramm erstellt wurden (ich bin nicht besorgt mit Hintergrundjobs oder anderen Benutzern auf den dir zu schreiben). Aber diese Methode ist nicht, was ich will, denn wenn eine Ausgabedatei nicht vor der Ausführung des Tests entfernt wurde (sie eigentlich sind sein, aber in einigen Fällen können sie nicht sein), wird diese Methode sagen, dass es nicht durch die erstellt wurde Testprogramm, weil es in dem dir war, bevor das Testprogramm ausgeführt wurde.

War es hilfreich?

Lösung

Nehmen Sie die Dateinamen aller Dateien vor dem Lauf, aber sind ihre Zeitstempel:

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

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

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

Und nach dem Lauf file2. Dann nutzen

comm -1 -3 file1 file2

Und es zeigt Ihnen die Linien eindeutig file2, die neuen Dateien sein muß, wenn ich nicht irre. Wenn sie vorher existiert, wird ihre Änderungszeit geändert hat, die Betreuung durch das %T@ Dingen genommen wird (Druck die Anzahl der Sekunden seit 1970 aus):

[js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file1
[js@HOST2 cpp]$ echo foo>bar
[js@HOST2 cpp]$ echo foo>baz
[js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file2
[js@HOST2 cpp]$ comm -1 -3 file1 file2
. 1230947309.0000000000
./bar 1230947308.0000000000
./baz 1230947309.0000000000
./file2 1230947315.0000000000
[js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file1
[js@HOST2 cpp]$ echo lol>bar
[js@HOST2 cpp]$ find -printf '%p %T@\n' | sort > file2
[js@HOST2 cpp]$ comm -1 -3 file1 file2
./bar 1230947359.0000000000
./file2 1230947362.0000000000
[js@HOST2 cpp]$`

Andere Tipps

Sie können tatsächlich berühren verwenden, um die Zeitstempel aller aktuellen Dateien in dem Verzeichnis zu weit in der Vergangenheit zu zwingen, wie zum Beispiel:

touch -t 200801010000.00 *

Wenn Sie dies tun, bevor Sie Ihren Test läuft, sollte es für „find -newer“ in der Zeit als genug Unterschied mehr sein, um ihn abzuholen. Wenn die Granularität 2 Minuten sind, konnte man alle aktuellen Dateien vor zehn Minuten gesetzt, die Zeitstempel-Datei vor 5 Minuten, dann Test ausgeführt werden.

So Ihr Skript wird:

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 ein anständiges von Perl installiert haben, können Sie folgendermaßen vorgehen vor 5 Minuten zu bekommen (oder -600 für 10 Minuten verwenden) in das richtige Format für „date -t“:

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

Wenn aus irgendeinem Grund, dass Sie nicht die Zeitstempel ä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

, die die gleiche Wirkung hat, sondern gibt Ihnen 10 Minuten, um einen Kaffee zu gehen (oder Ihr Gift der Wahl, wenn Sie kein Kaffeetrinker sind).

Wenn man bedenkt, wie find(1) implementiert ist, wird klar, warum dies manchmal nicht, wie Sie funktionieren könnte erwarten. Hier ein Tipp:

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

find(1) erhält die Datei mtime / Ctime / atime Werte den Systemaufruf stat(2) verwenden. 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 */

Auf Linux (und allgemein Unices) time_t eine ganze Zahl „s vom Beginn des Jahres 1970“ repräsentiert. Deshalb ist die feinste granuality, die begreifen -newer kann, ist nur eine Sekunde.

Warum nicht ein temporäres Verzeichnis, in dem die Tests laufen zu lassen? Verwenden Sie einen Zeitstempel-Namen auf dem Verzeichnis zu helfen, verfolgen, welche Ergebnisse passiert, wenn, und löschen Sie einfach das gesamte Verzeichnis, wenn Sie fertig.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top