Warum gibt ls -l eine andere Größe aus als ls -s?

38

Ich kann nicht herausfinden, warum ich die folgenden Ergebnisse erhalte:

ls -l sagt mir, dass die Größe einer bestimmten Datei (HISTORY) "581944" ist:

$ ls -l HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

ls -s sagt, es ist "572":

$ ls -s HISTORY
572 HISTORY

Ich muss natürlich dafür sorgen, dass die Werte eine vergleichbare Skala verwenden. Als erstes bestätige ich, dass ich mit --block-size 1in ls -ldasselbe Ergebnis wie zuvor erhalte:

$ ls -l --block-size 1 HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

Dann mache ich dasselbe, ls -sum einen Wert in der gleichen Skala zu erhalten:

$ ls -s --block-size 1 HISTORY 
585728 HISTORY

Unterschiedliche Ergebnisse! 581944 ≠ 585728 .

Ich habe versucht, vergleichbare Werte in umgekehrter Reihenfolge zu generieren -k, aber ich erhalte:

$ ls -lk HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 569 Feb 22 10:59 HISTORY
$ ls -sk HISTORY 
572 HISTORY

Wieder andere Ergebnisse, 569 ≠ 572 .

Ich habe versucht, --si anzugeben, um sicherzustellen, dass beide Optionen den gleichen Maßstab verwenden, ohne Erfolg:

$ ls -lk --si HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 582k Feb 22 10:59 HISTORY
$ ls -sk --si HISTORY 
586k HISTORY

... wieder andere Werte: 582k ≠ 586k .

Ich habe versucht, im Internet zu suchen, aber das einzige, was mir relevant erschien, war Folgendes :

Einige Dateien weisen "Löcher" auf, sodass die mit ls -s(...) angegebene Verwendung geringer ist als die mit angegebene Dateigröße ls -l. "

(Beachten Sie, dass in meinen Ergebnissen das Gegenteil passiert: ls -sGibt Größen zurück, die größer als ls -lund nicht kleiner sind.)

Inzwischen sagt diese Seite das

Es gibt keine elegante Möglichkeit, Unix-Dateilöcher zu erkennen.

Wie kann ich mit dieser Diskrepanz umgehen? Welcher dieser Werte kann als richtig angesehen werden? Könnte dies möglicherweise ein Fehler sein ls?

waldyrisch
quelle

Antworten:

47

Kurze Antwort:

  • ls -l gibt die Größe der Datei an (= die darin enthaltene Datenmenge)
  • ls -s --block-size 1 gibt die Größe der Datei im Dateisystem an

Lassen Sie uns zwei Dateien erstellen:

Eine Sparse-Datei mit einer Länge von 128 Byte (Eine Sparse-Datei ist eine Datei mit leeren Blöcken, siehe Sparse-Datei ):

# truncate -s 128 f_zeroes.img
# hexdump -vC f_zeroes.img 
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080

Eine weitere Datei mit zufälligen Daten, ebenfalls 128 Bytes groß:

# dd if=/dev/urandom of=f_random.img bs=1 count=128
# hexdump -vC f_random.img 
00000000  bc 82 9c 40 04 e3 0c 23  e6 76 79 2f 95 d4 0e 45  |...@...#.vy/...E|
00000010  19 c6 53 fc 65 83 f8 58  0a f7 0e 8f d6 d6 f8 b5  |..S.e..X........|
00000020  6c cf 1b 60 cb ef 06 c6  d0 99 c6 16 3f d3 95 02  |l..`........?...|
00000030  85 1e b7 80 27 93 27 92  d0 52 e8 72 54 25 4d 90  |....'.'..R.rT%M.|
00000040  11 59 a2 d9 0f 79 aa 23  2d 44 3d dd 8d 17 d9 36  |.Y...y.#-D=....6|
00000050  f5 ae 07 a8 c1 b4 cb e1  49 9e bc 62 1b 4f 17 53  |........I..b.O.S|
00000060  95 13 5a 1c 2a 7e 55 b9  69 a5 50 06 98 e7 71 83  |..Z.*~U.i.P...q.|
00000070  5a d0 82 ee 0b b3 91 82  ca 1d d0 ec 24 43 10 5d  |Z...........$C.]|
00000080

Wie Sie in der hexadezimalen Darstellung sehen können, haben beide Dateien die gleiche Datenmenge , obwohl der Inhalt sehr unterschiedlich ist.

Nun schauen wir uns das Verzeichnis an:

# ls -ls --block-size 1 f_*
1024 -rw-r--r-- 1 user user 128 Mar 18 15:34 f_random.img
   0 -rw-r--r-- 1 user user 128 Mar 18 15:32 f_zeroes.img
   ^                         ^
   |                         |
Amount which the           Actual file size
files takes on the fs

Der erste Wert wird durch die -s --block-size 1Option angegeben. Dies ist der von der Datei im Dateisystem belegte Speicherplatz .

Wie Sie sehen, belegt die Sparse-Datei keinen Speicherplatz, da das Dateisystem ( ext3in diesem Fall) intelligent genug war, um zu erkennen, dass es nur Nullen enthält. Auch die Datei mit zufälligen Daten belegt 1024 Bytes auf der Festplatte!

Der Wert hängt davon ab, wie das zugrunde liegende Dateisystem Dateien behandelt (Blockgröße, Funktion für Dateien mit geringer Dichte, ...).

In der sechsten Spalte steht die Größe der Datei, wenn Sie sie lesen würden - es ist die Datenmenge, die die Datei enthält, und es sind 128 Bytes für beide Dateien!

Phoibos
quelle
1
Vermutlich würde sogar eine leere Datei oder eine Datei mit Nullwerten irgendwo Platz in der Dateizuordnungstabelle einnehmen? Warum zählt das nicht ls -s?
Flimm
2
Metadaten zu Dateien werden in Inodes gespeichert. Jedes Dateisystem verfügt über eine begrenzte Anzahl von Inodes, die es verwenden kann. Um zu sehen, wie viele freie Inodes ein Dateisystem hat und wie groß diese sind: sudo tune2fs -l /dev/sdaX|grep Inodeoder df -ifür alle Partitionen.
Phoibos
1
Ich habe gerade einen interessanten, nicht künstlichen Weg gefunden, um dies zu überprüfen: Torrent-.part-Dateien scheinen gute Beispiele für Dateien mit Löchern zu sein: ls -lsh ~/Downloads/torrentsgibt mir zum Beispiel 92K -rw-r--r-- 1 waldir waldir 350M Sep 15 2012 video.avi.part. Das heißt, die 92K, durch die Option es zurückgegeben, der eigentliche Raum ist die Datei nimmt, Dateisystem-weise, und 350M, die von der Option -l zurückgegeben, ist die volle Größe der Datei würde , wenn es vollständig heruntergeladen wurde (dh wenn alle Bytes von Anfang bis Ende nicht Null waren). Siehe lists.freebsd.org/pipermail/freebsd-questions/2012-June/…
waldyrious
14

ls -sgibt die zugewiesene Größe der Datei an, immer ein Vielfaches der Zuordnungseinheit. ls -lgibt die tatsächliche Größe an. Eine einfache Möglichkeit zum Testen:

$ echo 1 > sizeTest
$ ls -l --block-size 1 sizeTest 
-rw-rw-r-- 1 g g 2 Mär 18 15:18 sizeTest
$ ls -s --block-size 1 sizeTest 
4096 sizeTest
guntbert
quelle