Perché ls -l produce una dimensione diversa da ls -s?


38

Non riesco a capire perché sto ottenendo i seguenti risultati:

ls -l mi dice che la dimensione di un determinato file (HISTORY) è "581944":

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

ls -s dice che è "572":

$ ls -s HISTORY
572 HISTORY

Devo ovviamente fare in modo che i valori utilizzino una scala comparabile. Quindi prima confermo che l'utilizzo di --block-size 1in ls -lmi dà lo stesso risultato di prima:

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

Quindi faccio lo stesso per ls -sottenere un valore nella stessa scala:

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

Risultati diversi! 581944 ≠ 585728 .

Ho provato a generare valori comparabili viceversa, usando -k, ma ottengo:

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

Ancora una volta, risultati diversi, 569 ≠ 572 .

Ho provato a specificare --si per assicurarmi che entrambe le opzioni stessero usando la stessa scala, senza risultati:

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

... ancora, valori diversi: 582k ≠ 586k .

Ho provato a cercare sul web, ma l'unica cosa che ho trovato che sembrava rilevante era questa :

In alcuni file sono presenti "buchi", pertanto l'utilizzo elencato da ls -s(...) è inferiore alla dimensione del file elencata da ls -l. "

(nota che nei miei risultati accade il contrario: ls -srestituisce dimensioni maggiori di ls -l, non inferiori.)

Nel frattempo, questa pagina dice questo

non esiste un modo elegante per rilevare buchi di file Unix.

Quindi, come posso affrontare questa discrepanza? Quale di questi valori può essere considerato corretto? Questo potrebbe forse essere un bug ls?

Risposte:


47

Risposta breve:

  • ls -l indica la dimensione del file (= la quantità di dati che contiene)
  • ls -s --block-size 1 indica la dimensione del file nel file system

Creiamo due file:

Un file sparse di 128 byte di lunghezza (un file sparse è un file contenente blocchi vuoti, vedere File sparse ):

# 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

Un altro file con dati casuali, anche di 128 byte:

# 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

Quindi, come puoi vedere nella rappresentazione esadecimale, entrambi i file hanno la stessa quantità di dati , sebbene il contenuto sia abbastanza diverso.

Ora diamo un'occhiata alla directory:

# 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

Il primo valore è dato -s --block-size 1dall'opzione, è la quantità di spazio utilizzata dal file nel file system .

Come puoi vedere, il file sparse occupa spazio zero, poiché il file system ( ext3in questo caso) è stato abbastanza intelligente da riconoscere che contiene solo zero. Inoltre, il file con dati casuali occupa 1024 byte sul disco!

Il valore dipende da come il file system sottostante tratta i file (dimensione del blocco, capacità dei file sparsi, ...).

Nella sesta colonna è la dimensione del file se lo leggi: è la quantità di dati che il file contiene ed è 128 byte per entrambi i file!


1
Presumibilmente, anche un file vuoto o un file pieno di valori null occuperebbe spazio nella tabella di allocazione dei file da qualche parte? Perché non ls -sconta questo?
Flimm,

2
I metadati sui file sono archiviati in inode. Ogni file system ha una quantità limitata di inode che può usare. Per vedere quanti inode gratuiti ha un file system e la sua dimensione:, sudo tune2fs -l /dev/sdaX|grep Inodeo df -iper tutte le partizioni.
phoibos,

1
Ho appena trovato un interessante modo non-artificiale per verificare questo: i file torrent .part sembrano essere buoni esempi di file con fori: ls -lsh ~/Downloads/torrentsmi dà, per esempio, 92K -rw-r--r-- 1 waldir waldir 350M Sep 15 2012 video.avi.part. Cioè, il 92K, restituito dall'opzione -s, è lo spazio effettivo che il file occupa, filesystem-saggio, e 350M, restituito dall'opzione -l, è la dimensione completa che il file avrebbe se fosse completamente scaricato (cioè se tutti i byte, dall'inizio alla fine, fossero diversi da zero). Vedi lists.freebsd.org/pipermail/freebsd-questions/2012-June/…
waldyrious

14

ls -sindica la dimensione allocata del file, sempre un multiplo dell'unità di allocazione. ls -lindica la dimensione effettiva. Un modo semplice per testare:

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.