Eu sou relativamente novo no Ubuntu e gostaria de aprender mais programação Linux.
Cada vez que eu imprimo ls -l
e comparo novamente meus próprios códigos para adicionar st_blocks
de cada arquivo, o resultado é sempre stat block sendo o dobro do ls
tamanho do bloco?
Existe alguma explicação específica para isso?
Na linha de comando:
$ ls -ls
total 28
4 ... test
20 ... test.c
4 ... test.txt
Programa para somar não-'.' arquivos:
$ myls
total 56
8 ... test
40 ... test.c
8 ... test.txt
Extrato do código usado em um loop:
...
...
if (dirName[0] != '.') {
blocksize += buf.st_blocks;
}
return blocksize;
...
Estado
O tamanho do bloco usado como unidade
st_blocks
é sempre de 512 bytes em sistemas que usam o kernel Linux (que inclui todos os sistemas GNU/Linux, como o Ubuntu). É desse tamanho na maioria dos outros sistemas operacionais do tipo Unix também.Como Stephen Kitt explica em sua resposta a Por que st_blocks sempre é relatado em blocos de 512 bytes? :
(ênfase minha)
stat(2) lista os membros de
struct stat
, que incluem:O
stat
comando (veja stat(1) ) também usa um tamanho de bloco de 512 bytes. Por exemplo, conforme revelado porls -l
, no meu sistema/bin/nano
tem 208480 bytes e a saída destat /bin/nano
includesBlocks: 408
.ls
ls -l
imprime tamanhos de arquivo em bytes por padrão, masls -s
os imprime em blocos de 1024 bytes. Existemls
implementações para alguns sistemas do tipo Unix que padronizam para blocos de 512 bytes, mas tanto GNU ls (que fornece/bin/ls
no Ubuntu) quantobusybox ls
(a outrals
implementação no Ubuntu) são padronizados para blocos de 1024 bytes. Você não precisa passar-k
por esse comportamento, embora possa ser necessário em alguns outros sistemas.Ao imprimir tamanhos de arquivo em blocos, o
ls
comando do Ubuntu é padronizado para blocos de 1024 bytes porque eles são mais convenientes. Você pode mudar isso com--block-size
se quiser. Na prática, acredito que as abordagens mais populares são:-l
sem-s
para obter um tamanho em bytes (que é efetivamente um tamanho de bloco de 1)-l
ou-s
com-h
para imprimir tamanhos mais legíveis com etiquetas de unidade-s
e usando o padrão de 1024 bytesAlguns utilitários GNU imprimem blocos de 512 bytes quando executados em modo de compatibilidade POSIX .
du
é um caso particularmente óbvio; compare a saída dedu /bin/nano
com a dePOSIXLY_CORRECT= du /bin/nano
. GNU ls também se comporta dessa maneira quando-s
é passado, mas a saída com-l
e não-s
, assim como a saída com-h
, não é afetada. (A saída sem opções também não é afetada, pois isso não imprime um tamanho.)Além de suportar
--block-size
, o GNU ls também respeita algumas outras variáveis de ambiente, principalmenteBLOCK_SIZE
. Ao contrárioPOSIXLY_CORRECT
, isso afeta não só,ls -s
mas tambémls -l
sem-s
. Se, por algum motivo, vocêBLOCK_SIZE
definiu, mas não deseja usá-lo, e desejals -s
usar blocos de 1024 bytes, passar-k
com-s
o substituirá.Existem outras maneiras de ajustar isso, e alguma sutileza está envolvida quando mais de uma maneira é usada simultaneamente. Para detalhes rápidos, veja os exemplos abaixo e ls(1) (
man ls
). Para detalhes completos, leia o manual GNU coreutils (que também deve estar disponível localmente: runinfo coreutils
), especialmente a seção 2.3 Block size .ls
exemplosAqui estão alguns exemplos para controlar o tamanho da unidade mostrado por
ls
.ls -l
imprime tamanhos em bytes:ls -s
imprime tamanhos em blocos de 1024 bytes:Adicionando
-h
a qualquer um imprime em formato legível por humanos:Passar
-l
e-s
anexar o que quer-s
que apareça por si só, em vez de afetar as colunas de tamanho produzidas por-l
:Adicionando
-k
os comandos mostrados acima com-s
ou-l
não altera a saída, porque o GNU ls já padroniza para blocos de 2014 bytes com-s
, e-l
mostra tamanhos em bytes e não é afetado por-k
. No entanto,-k
tem efeito em situações mais complicadas (veja abaixo).Adicionando
--block-size=size-in-bytes
faz com que os tamanhos sejam impressos em blocos do tamanho especificado:Ao contrário de algumas outras opções, a
--block-size
opção tem esse efeito mesmo na coluna de tamanho produzida porls -l
que normalmente seria mostrada em bytes:--block-size
não é substituído por-k
, mesmo que-k
apareça depois dele:(Meus exemplos usam potências de dois, mas o operando
--block-size
não precisa ser uma potência de dois. Além disso,-s
e-l
aparentemente usam regras de arredondamento diferentes.)Definir a
BLOCK_SIZE
variável de ambiente tem um efeito semelhante a passar--block-size
:A diferença de efeito entre a
--block-size
opção e aBLOCK_SIZE
variável de ambiente é que aBLOCK_SIZE
variável de ambiente é mais frequentemente substituída por opções.-k
substituiçõesBLOCK_SIZE
:Isso funciona com
-s
. Mas-k
não substitui osBLOCK_SIZE
tamanhos exibidos por-l
, simplesmente porque (conforme detalhado acima)-k
não afeta isso:--block-size
também sobrepõeBLOCK_SIZE
. Como--block-size
afeta tanto-s
e-l
, ele substituiBLOCK_SIZE
ambos:Definir a
POSIXLY_CORRECT
variável de ambiente, mesmo para a string vazia, fazls -s
com que sejam usados blocos de 512 bytes. As opções-h
,-k
e--block-size
substituem esse efeito, produzindo seu comportamento especificado. Mas ao contrário de--block-size
eBLOCK_SIZE
,ls -l
ainda imprime tamanhos em bytes.BLOCK_SIZE
tem precedência sobrePOSIXLY_CORRECT
:As opções que afetam o tamanho do bloco também têm precedência sobre
POSIXLY_CORRECT
, poisPOSIXLY_CORRECT
está apenas alterando o tamanho do bloco padrão. Em particular,-k
substituiPOSIXLY_CORRECT
:ls
- outras opçõesNão mostrei todas as combinações de opções relevantes e variáveis de ambiente.
Além disso, existem mais duas variáveis de ambiente relacionadas a como o GNU ls escolhe os tamanhos dos blocos:
BLOCKSIZE
(observe que não há sublinhado) se comporta comoBLOCK_SIZE
forls -s
, mas nãols -l
. Ele adiaBLOCK_SIZE
quando isso está presente.LS_BLOCK_SIZE
comporta-se comoBLOCK_SIZE
mas afeta apenasls
mas nãodu
edf
. Se ambosLS_BLOCK_SIZE
eBLOCK_SIZE
estiverem definidos,LS_BLOCK_SIZE
será usado.Essas variáveis de ambiente, como as outras, têm precedência sobre
POSIXLY_CORRECT
.Como mencionado acima, veja a seção 2.3 Tamanho do bloco no manual GNU coreutils para mais informações, incluindo detalhes sobre eles. Este manual, que você pode ler na linha de comando digitando
info coreutils
, é muito mais detalhado do que as manpagesls
e outros comandos fornecidos pelo coreutils.