Por que ls -l produz um tamanho diferente de ls -s?

38

Não consigo entender por que estou obtendo os seguintes resultados:

ls -l diz-me que o tamanho de um determinado arquivo (HISTORY) é "581944":

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

ls -s diz que é "572":

$ ls -s HISTORY
572 HISTORY

Obviamente, preciso fazer com que os valores usem uma escala comparável. Primeiro, confirmo que o uso de --block-size 1in ls -lme dá o mesmo resultado de antes:

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

Então faço o mesmo para ls -sobter um valor na mesma escala:

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

Resultados diferentes! 581944 ≠ 585728 .

Tentei gerar valores comparáveis ​​ao contrário, usando -k, mas obtive:

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

Novamente, resultados diferentes, 569 × 572 .

Tentei especificar --si para garantir que ambas as opções usassem a mesma escala, sem sucesso:

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

... novamente, valores diferentes: 582k ≠ 586k .

Tentei pesquisar na web, mas a única coisa que pude achar relevante era o seguinte :

Alguns arquivos têm "brechas" neles, de modo que o uso listado por ls -s(...) é menor que o tamanho do arquivo listado por ls -l".

(observe que, em meus resultados, acontece o oposto: ls -sretorna tamanhos maiores que ls -l, não menores.)

Enquanto isso, esta página diz que

não há uma maneira elegante de detectar falhas no arquivo Unix.

Então, como posso lidar com essa discrepância? Quais desses valores podem ser considerados corretos? Isso poderia ser um bug ls?

valioso
fonte

Respostas:

47

Resposta curta:

  • ls -l fornece o tamanho do arquivo (= a quantidade de dados que ele contém)
  • ls -s --block-size 1 fornece o tamanho do arquivo no sistema de arquivos

Vamos criar dois arquivos:

Um arquivo esparso de 128 bytes (Um arquivo esparso é um arquivo que contém blocos vazios, consulte Arquivo Esparso ):

# 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

Outro arquivo com dados aleatórios, também com tamanho de 128 bytes:

# 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

Portanto, como você pode ver na representação hexadecimal, os dois arquivos têm a mesma quantidade de dados , embora o conteúdo seja bem diferente.

Agora, vejamos o diretório:

# 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

O primeiro valor é dado pela -s --block-size 1opção, é a quantidade de espaço usada pelo arquivo no sistema de arquivos .

Como você pode ver, o arquivo esparso ocupa zero espaço, pois o sistema de arquivos ( ext3neste caso) era inteligente o suficiente para reconhecer que contém apenas zeros. Além disso, o arquivo com dados aleatórios ocupa 1024 bytes no disco!

O valor depende de como o sistema de arquivos subjacente trata os arquivos (tamanho do bloco, capacidade de arquivo esparso, ...).

Na sexta coluna, está o tamanho do arquivo, se você o ler - é a quantidade de dados que o arquivo contém e são 128 bytes para os dois arquivos!

phoibos
fonte
11
Presumivelmente, mesmo um arquivo vazio ou um arquivo cheio de valores nulos ocuparia espaço na tabela de alocação de arquivos em algum lugar? Por que não ls -sconta isso?
Flimm 19/03/2013
2
Os metadados sobre arquivos são armazenados em inodes. Cada sistema de arquivos possui uma quantidade limitada de inodes que pode ser usada. Para ver quantos inodes livres um sistema de arquivos possui e o tamanho deles:, sudo tune2fs -l /dev/sdaX|grep Inodeou df -ipara todas as partições.
Phoibos
11
Acabei de encontrar uma maneira interessante e não artificial de verificar isso: arquivos .part torrent parecem ser bons exemplos de arquivos com falhas: ls -lsh ~/Downloads/torrentsme dá, por exemplo 92K -rw-r--r-- 1 waldir waldir 350M Sep 15 2012 video.avi.part,. Ou seja, o 92K, retornado pela opção -s, é o espaço real que o arquivo ocupa, em termos de sistema de arquivos, e 350M, retornado pela opção -l, é o tamanho total que o arquivo teria se fosse completamente baixado (por exemplo, se todos os bytes, do início ao fim, forem diferentes de zero). Veja lists.freebsd.org/pipermail/freebsd-questions/2012-June/…
waldyrious
14

ls -sinforma o tamanho alocado do arquivo, sempre um múltiplo da unidade de alocação. ls -linforma o tamanho real. Uma maneira fácil de testar:

$ 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
fonte