EXT3: Se o tamanho do bloco for 4K, por que o ls -l mostra os tamanhos dos arquivos abaixo disso?

16

Se você executar ls -l em um arquivo que contenha uma letra, ela será listada como 2B de tamanho. Se o seu sistema de arquivos está em blocos de 4k, eu pensei que ele arredondava arquivos até o tamanho do bloco? É porque ls -l realmente lê a contagem de bytes do inode? Em que circunstâncias você é arredondado para bloquear respostas versus respostas reais de contagem de bytes nos utilitários Linux 2.6 Kernel GNU?

    
por Gregg Leventhal 28.04.2014 / 21:57

3 respostas

21

Eu acho que você tem aquela letra no arquivo com echo a > file ou vim file , o que significa que você terá essa letra e uma nova linha adicional (dois caracteres, portanto, dois bytes). ls -l mostra o tamanho do arquivo em bytes, não blocos (para ser mais específico: arquivo comprimento ):

$ echo a > testfile
$ ls -l testfile
-rw-r--r-- 1 user user 2 Apr 28 22:08 testfile
$ cat -A testfile
a$

(observe que cat -A exibe novas linhas como $ character)

Em contraste com ls -l , du mostrará o tamanho real ocupado no disco:

$ du testfile
4

(na verdade, du mostra o tamanho em unidades de 1kiB, então aqui o tamanho é 4 × 1024 bytes = 4096 bytes = 4 kiB, que é o tamanho do bloco neste sistema de arquivos)

Para que ls mostre isso, você terá que usar a opção -s em vez de / além de -l :

$ ls -ls testfile
4 -rw-r--r-- 1 user user 2 Apr 28 22:08 testfile

A primeira coluna é o tamanho alocado, novamente em unidades de 1kiB. A última pode ser alterada especificando --block-size , por exemplo,

$ ls -ls --block-size=1 testfile
4096 -rw-r--r-- 1 aw aw 2 Apr 28 22:08 testfile
    
por 28.04.2014 / 22:14
9

Acho que a resposta mais profunda é a seguinte:

Logical file length and disk space occupied are really different things.

Como as outras respostas mostram, em princípio, um arquivo criado com dois bytes tem comprimento de dois bytes (mostrado por ls -l ) e ocupa 4 KiB (exibido por du ou ls -ls ).

Veja:

1& [:~/tmp] % echo -n A > test
1& [:~/tmp] % ls -l test
-rw-rw-r-- 1 romano romano 1 Apr 28 14:31 test
1& [:~/tmp] % du test
4 test

Ok, test tem comprimento 1 e tamanho (no disco) 4 KiB. Mas:

1& [:~/tmp] % truncate -s +8191 test
1& [:~/tmp] % ls -l test
-rw-rw-r-- 1 romano romano 8192 Apr 28 14:33 test
1& [:~/tmp] % du test
4   test

(o primeiro comando adiciona 8191 zero bytes a test ), agora o teste tem comprimento 8192 mas ainda ocupa 4 KiB no disco (tem um "buraco") nele (1).

Alguns sistemas de arquivos também podem compactar arquivos curtos para que ocupem menos espaço compartilhando blocos (veja por exemplo tail packing ) e outros como o btrfs copia na gravação , então a relação entre um arquivo, sua duração lógica e como muito espaço que ocupa em um disco é complexo.

Notas de rodapé:

(1) Não é realmente um buraco , é no final ... mas ainda assim, funciona até o final do exemplo.

    
por 28.04.2014 / 22:42
5

ls -l é apenas um formato longo. ls -ls é usado para exibir o tamanho do bloco.

Teste

echo "1" > 1.txt

bash-3.2$ ls -l 1.txt
-rw-rw-r-- 1 ramesh ramesh 2 Apr 28 15:15 1.txt

Como podemos ver, o tamanho do arquivo está listado como 2B. No entanto, se você precisar verificar o tamanho do bloco, será necessário executar o comando abaixo.

bash-3.2$ ls -ls 1.txt
4 -rw-rw-r-- 1 ramesh ramesh 2 Apr 28 15:15 1.txt

O 4 acima exibe o tamanho do bloco usado. Também podemos verificar o mesmo usando o comando stat .

bash-3.2$ stat 1.txt
  File: '1.txt'
  Size: 2               Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 48267720    Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  505/  ramesh)   Gid: (  508/  ramesh)
Access: 2014-04-28 15:17:31.000000000 -0500
Modify: 2014-04-28 15:15:58.000000000 -0500
Change: 2014-04-28 15:15:58.000000000 -0500

Agora surge a pergunta: por que ls -ls lista o tamanho do bloco como 4, enquanto stat exibe o tamanho do bloco como 8. A razão para esse comportamento é claramente explicada na resposta aqui .

Many disks have a sector size of 512 bytes, meaning that any read or write on the disk transfers a whole 512-byte sector at a time. It is quite natural to design filesystems where a sector is not split between files (that would complicate the design and hurt performance); therefore filesystems tend to use 512-byte chunks for files. Hence traditional utilities such as ls and du indicate sizes in units of 512-byte chunks.

    
por 28.04.2014 / 22:21