Kiedy `ls -s` wypisuje„ 0 ”

13

Oczywiście jest to standardowy sposób testowania, czy plik jest pusty test -s FILE, ale jeden z naszych klientów otrzymał skrypt zawierający takie testy:

RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
    echo "Badness: Log not empty"
    exit 25
fi

z twierdzeniami dostawcy, że działa w dwóch środowiskach, w których go przetestowali. Nie trzeba dodawać, że zawiodło to w dwóch miejscach, w których go testowałem.

Zainteresowałem się. Kiedy ls -sdrukuje 0puste pliki?

Oto moje dotychczasowe ustalenia:

  • GFS w systemie Linux: 4
  • ext4 w systemie Linux: 0
  • ZFS w systemie Solaris: 1
  • UFS w systemie Solaris: 0
  • jfs w systemie AIX: 0
  • VxFS w systemie HP-UX: 0
  • HFS w systemie HP-UX: 0
  • HFS w systemie Mac OS X: 0

Nie badałem jeszcze sieciowych systemów plików.

Pytanie: Jak mogę elegancko wyjaśnić innym, że ich skrypty są nieprawidłowe ?

Moim zdaniem „poprawną” wersją byłoby:

if test ! -s ./log/cr_trig.log
then
    echo "Badness: Log not empty"
    exit 25
fi
MattBianco
źródło
5
Po prostu pokaż im swoje testy. Masz twarde dane, które dowodzą, że ich test nie jest przenośny, czego więcej potrzebujesz?
Mat.
Jedno z najciekawszych pytań, jakie do tej pory widziałem na tym serwerze. Szkoda, że ​​można wydać tylko jeden punkt.
ktf
@ktf Zawsze możesz przyznać nagrodę.
Joe

Odpowiedzi:

6

Bardzo ciekawe znalezisko. Chociaż nigdy nie ls -ssprawdzałem, czy plik jest pusty, czy nie, zakładałbym, że raportuje również 0o pustych plikach.

Na twoje pytanie: Jak Mat już skomentował, pokaż im swoje wyniki testu. Aby objaśnić im wyniki, podaj stan, który ls -spodaje liczbę przydzielonych bloków w systemie plików, a nie rzeczywisty rozmiar w bajtach. Oczywiście niektóre implementacje systemu plików alokują bloki, nawet jeśli nie muszą przechowywać żadnych danych zamiast przechowywać tylko wskaźnik NULL w i-węzle.

Wyjaśnienie tego może być związane z wydajnością. Tworzenie pustych plików, które pozostaną puste, jest wyjątkiem od normalnego przetwarzania (najczęstszym zastosowaniem, jakie widziałem, byłoby tworzenie plików stanu, w których istnienie pliku reprezentuje pewien stan oprogramowania).

Ale zwykle utworzony plik wkrótce otrzyma pewne dane, więc projektanci pewnego FS mogli założyć, że opłaca się natychmiast przydzielić blok danych po utworzeniu pliku, więc kiedy pierwsze dane dotrą, to zadanie jest już wykonane.

Drugim powodem może być to, że plik zawierał dane w przeszłości, które zostały usunięte. Zamiast zwolnić ostatni blok danych, warto zatrzymać ten blok danych do ponownego wykorzystania przez ten sam plik.

EDYTOWAĆ:

Przyszedł mi do głowy jeszcze jeden powód: systemy plików, w których znalazłeś wartości> 0, to ZFS , implementacja RAID + LVM + FS i GFS , klastrowy system plików. Oba mogą wymagać przechowywania metadanych w celu zachowania integralności pliku, który nie jest przechowywany w i-węzłach. Możliwe, że ls -sliczy się w blokach danych przydzielonych dla tych metadanych.

ktf
źródło
4

W przeciwieństwie do większości (jeśli nie wszystkich) innych systemów plików, ZFS nie przydziela wstępnie statycznej tablicy i-węzłów. Utworzenie pustego pliku w ZFS spowoduje następnie użycie nowego bloku danych, który jest tym zgłaszanym przez ls -s.

Podejrzewam, że GFS musi przechowywać dane synchronizacji / blokady prowadzące do innego niezerowego wyniku.

jlliagre
źródło
2

ls -s zgłasza liczbę bloków przydzielonych do pliku, bez uwzględnienia tego, co jest zapisane bezpośrednio we wpisie katalogu.

W większości przypadków liczba bloków jest liczbą bajtów podzieloną przez rozmiar bloku w bajtach, zaokrągloną w górę.

Liczba bloków może być mniejsza niż dla pliku rzadkiego . Na przykład w większości systemów plików spowoduje to utworzenie pliku o długości 8192 bajtów obejmującego 0 bloków:

$ perl -e 'truncate STDOUT, 8192' >a
$ ls -l a
-rw-r--r-- 1 gilles gilles 8192 Nov  1 21:32 a
$ ls -s a
0 a

I odwrotnie, liczba bloków może być większa, jeśli system plików wstępnie przydziela bloki dla plików lub używa bloków do przechowywania metadanych. Nie dziwię się, że Zfs ma nieoczywistą zgodność między rozmiarem pliku a liczbą bloków, biorąc pod uwagę dużą liczbę funkcji, jakie oferuje i jego ukierunkowanie na duże systemy plików; Nie znam szczegółów, ale liczba bloków zależy nie tylko od rozmiaru plików, ale także od ich historii (możesz mieć więcej niż jeden blok w pustym pliku, jeśli jest to wynikiem obcięcia większego pliku).

Aby wyjaśnić, dlaczego ls -sjest zły: nie liczy rozmiaru pliku, ale ilość zależną od systemu plików. Jest to bardzo pośredni sposób na określenie, czy plik jest pusty, wymagający zewnętrznego narzędzia ( ls) i analizy; zamiast tego powinni używać test -s, który nie wymaga analizowania, i wykonuje dokładnie to, co jest wymagane. Jeśli uważają, że ls -sjest to dobry sposób na sprawdzenie, czy plik jest pusty, należy na nich spoczywać obowiązek uzasadnienia jego działania.

Gilles „SO- przestań być zły”
źródło