/ / Warunki tworzenia sygnatur czasowych dla systemu Linux - linux, find, timestamp

Warunki tworzenia sygnatur czasowych dla Linuksa - linux, find, timestamp

Próbuję zrobić to, co moim zdaniem jest prostepod Linuksem. Mam skrypt bash, który uruchamia różne programy testowe i chcę ustalić, które pliki w bieżącym katalogu zostały utworzone przez programy testowe. Więc robię coś takiego:

dotknij pliku sygnatury czasowej uruchom test find -newer timestamp-file -type f> lista-plików rm -f plik sygnatury czasowej

Zmniejsza ziarnistość find -newer jest słaba, więc zwykle zdarza się, że niektóre pliki wygenerowane przez program testowy wyświetlają się jako OLDER niż plik sygnatury czasowej. Więc spróbowałem tego:

ls -tr1 | sed "1, / znacznik czasu pliku / d"

aby wygenerować tę samą listę. To zazwyczaj działa, ale nie zawsze. Nadal dochodzę do sytuacji, w której pliki wygenerowane przez test są starsze niż plik sygnatury czasowej.

Dzięki!

P.S. Mogę to zrobić w inny sposób, biorąc dwie migawki katalogu, jedną przed uruchomieniem programu testowego, a następnie jedną po, i porównując je. Wszystkie pliki z drugiej listy, które nie są w pierwszej, muszą zostać utworzone przez program testowy (nie dotyczy to zadań w tle lub innych użytkowników zapisujących do katalogu) .Ale ta metoda nie jest tym, czego chcę, ponieważ jeśli wynik jest plik nie został usunięty przed uruchomieniem testu (powinny one być, ale w niektórych przypadkach może nie być), metoda ta powie, że nie został stworzony przez program testowy, ponieważ był w katalogu przed programem testowym został uruchomiony.

Odpowiedzi:

1 dla odpowiedzi № 1

Weź nazwy plików wszystkich plików przed uruchomieniem, ale dołącz ich sygnatury czasowe:

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

Jeśli nie masz dostępnej opcji, możesz użyć stat dla tego zadania:

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

</ sub>

A po biegu do file2. Następnie użyj

comm -1 -3 file1 file2

I pokaże Ci linie unikalne dla file2, które muszą być nowymi plikami, jeśli się nie mylę .Jeśli istniały wcześniej, czas ich modyfikacji ulegnie zmianie, co %T@ thingy (drukowanie liczby sekund od 1970 roku):

[js @ HOST2 cpp] $ find -printf "% p% T @ n" | sort>plik1 [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 plik1 plik2 . 1230947309.0000000000 ./bar 1230947308.0000000000 ./baz 1230947309.0000000000 ./file2 1230947315.0000000000 [js @ HOST2 cpp] $ find -printf "% p% T @ n" | sort> plik1 [js @ HOST2 cpp] $ echo lol> bar [js @ HOST2 cpp] $ find -printf "% p% T @ n" | sort> file2 [js @ HOST2 cpp] $ comm -1 -3 plik1 plik2 ./bar 1230947359.0000000000 ./file2 1230947362.0000000000 [js @ HOST2 cpp] $ `

3 dla odpowiedzi № 2

W rzeczywistości możesz używać dotyku, aby wymusić znaczniki czasu wszystkich bieżących plików w katalogu w przeszłości, na przykład:

touch -t 200801010000.00 *

Jeśli zrobisz to przed uruchomieniem testu, różnica powinna zająć więcej niż czas "find -newer"Aby ją odebrać. Jeśli szczegółowość wynosi dwie minuty, możesz ustawić wszystkie bieżące pliki na dziesięć minut temu, plik sygnatury czasowej na 5 minut temu, a następnie uruchom test.

Twój skrypt staje się:

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

Zakładając, że masz przyzwoitą instalację Perla, możesz wykonać 5 minut (lub użyć -600 przez 10 minut) w odpowiednim formacie dla "date -t":

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

Jeśli z jakiegoś powodu nie możesz zmienić znaczników czasu, użyj:

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

który ma ten sam efekt, ale daje ci dziesięć minut na kawę (lub twoją truciznę, jeśli nie jesteś pijącym kawę).


2 dla odpowiedzi nr 3

Jeśli rozważasz, w jaki sposób find(1) jest zaimplementowane, będzie jasne, dlaczego czasami może nie działać zgodnie z oczekiwaniami. Oto podpowiedź:

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

find(1) uzyskuje wartości mtime / ctime / atime pliku przy użyciu wywołania systemowego stat(2). Oto elementy struct stat od <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 */

W systemie Linux (i ogólnie Unice) time_t jest liczbą całkowitą reprezentującą "sekundy od początku 1970 roku". Dlatego najlepsza granalność tego -newer zrozumienie to tylko jedna sekunda.


0 dla odpowiedzi nr 4

Dlaczego nie utworzyć tymczasowego katalogu, w którym doprzeprowadzić testy? Użyj nazwy opartej na sygnaturze czasowej w katalogu, aby śledzić, które wyniki wystąpiły, i po prostu usuń cały katalog po zakończeniu.