2012-07-05 10 views
6

QNX (Neutrino 6.5.0) wykorzystuje implementację open source KSH jako skorupy. Wiele dostarczonych skryptów, w tym skrypty startowe systemu, używa konstrukcji, takich jak: Różnica pomiędzy „pliku testowego -a” i „plik Test -EF pliku”

if ! test /dev/slog -ef /dev/slog; then 
    # do something 
fi 
do sprawdzania, czy w systemie plików istnieje menedżer zasobów. Szukałem i mogłem znaleźć tylko bardzo dray wyjaśnienia, które sprawdzają, czy te dwa parametry są w rzeczywistości tym samym plikiem. Ponieważ określona nazwa pliku jest taka sama, wydaje się, że po prostu zmniejsza się do sprawdzenia, czy plik istnieje.

Sprawdziłem zachowanie test -a i test -e (oba wydają się sprawdzać obecność pliku dowolnego typu zgodnie z różnymi dokumentami, które przeczytałem) i wydają się również działać.

Czy są jakieś różnice w sprawdzeniach przeprowadzonych między -ef i -a/-e? Czy używa się -ef jakiejś próby zabezpieczenia się przed kondycją wyścigu w przypadku istnienia pliku?

+0

Wydaje się, że może rzeczywiście być sprawdzenie, czy istnieje plik dla dwóch różnych stat() zwraca. Czy pozycja/dev zostaje usunięta przez sterownik/menedżera (np. Po wyłączeniu) tylko wtedy, gdy ktoś sprawdza, czy istnieje? – jhfrontz

+0

@jhfrontz: Nie jestem do końca pewien, co masz na myśli, ale (jako przykład)/dev/walić tylko pseudo urządzenie zostanie usunięte, gdy kierowca zostanie zabity, które normalnie nie zdarzają się w środku zaproszenia do 'test' od jest częścią początkowego skryptu uruchamiania systemu. W normalnym przypadku/dev/walić proces może napisać do urządzenia do dziennika w pliku/konsoli/pamięci, a jednocześnie może skończyć z inną nazwą, urządzenie narażone na/dev powinny być takie same jak przed napisz do/dev/slog. – tinman

+0

Jestem spekulacje, że stat'ing urządzenie ma jakiś efekt uboczny (np skłoniło kierowcy/menedżer zrobić jakieś sprzątanie), że jako pierwszy stat() rozmowy (z 'test') jest zakończona, plik/urządzenie jest usuwane/zastępowane przez sterownik - co powoduje, że druga stat() pobiera różne informacje, co z kolei powoduje niepowodzenie testu. Minęło trochę czasu, odkąd użyłem QNX, ale [strona man maniaka] (http: //www.qnx.com/developers/docs/6.3.0SP3/neutrino/utilities/s/slogger.html) sugeruje, że są efekty uboczne wchodzące w interakcje z/dev/slog (np. rozłączenie usuwa log). – jhfrontz

Odpowiedz

4

Przeglądanie strace na kopii systemu Ubuntu Linux: ksh nie wykazuje istotnych różnic. Jedno połączenie z numerem stat.

$ strace test /tmp/tmp.geLaoPkXXC -ef /tmp/tmp.geLaoPkXXC 

pokazał to:

mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f11dc80b000 
close(3)        = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
close(1)        = 0 
close(2)        = 0 

... natomiast

$ strace test -a /tmp/tmp.geLaoPkXXC 

pokazał to:

fstat(3, {st_mode=S_IFREG|0644, st_size=7220736, ...}) = 0 
mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6b49e2b000 
close(3)        = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
close(1)        = 0 
close(2)        = 0 

Jeden stat vs dwóch.

1

Nie wiemy, w jaki sposób kod używa statystyki dokładnie bez kodu, musimy znaleźć różnicę za pomocą kodu.

/* code for -ef */ 
return (stat (argv[op - 1], &stat_buf) == 0 
        && stat (argv[op + 1], &stat_spare) == 0 
        && stat_buf.st_dev == stat_spare.st_dev 
        && stat_buf.st_ino == stat_spare.st_ino); 


/* code for -e/-a */ 
    case 'a':     /* file exists in the file system? */ 
    case 'e': 
     return stat (argv[pos - 1], &stat_buf) == 0; 

Tak więc, jeśli nazwy są takie same i dwa stat() o tej samej nazwie zwróci tę samą wartość, a następnie, test -a/-e file jest taka sama jak test file -ef file. Wiemy, że pierwszy warunek jest spełniony, a wiemy, że drugi warunek jest również prawdą, z komentarzy @tinman

Powiązane problemy