Como obter o tamanho real do diretório (fora de du)?

16

Como obtenho o tamanho real do diretório usando as ferramentas padrão do UNIX / Linux?

Pergunta alternativa: Como obtenho du para mostrar o tamanho real do diretório (não uso do disco)?

Como as pessoas parecem ter diferentes definições do termo "tamanho": Minha definição de "tamanho do diretório" é a soma de todos os arquivos comuns nesse diretório.

Eu não me importo com o tamanho do diretório inode ou o que quer que seja (tamanho do bloco de blocos *) que os arquivos ocupam no respectivo sistema de arquivos. Um diretório com 3 arquivos, 1 byte cada, tem um tamanho de diretório de 3 bytes (pela minha definição).

Calcular o tamanho do diretório usando du parece não ser confiável.
Por exemplo, mkdir foo && du -b foo reporta "4096 foo", 4096 bytes em vez de 0 bytes. Com diretórios muito grandes, o tamanho do diretório relatado por du -hs pode ser desativado em 100 GB (!) E mais (sistema de arquivos compactado).

Então, o que (ferramenta / opção) tem que ser usado para obter o tamanho real do diretório?

    
por basic6 02.06.2013 / 18:25

5 respostas

8

Aqui está um script que exibe um tamanho de diretório legível usando ferramentas padrão do Unix (POSIX).

#!/bin/sh
find ${1:-.} -type f -exec ls -lnq {} \+ | awk '
BEGIN {sum=0} # initialization for clarity and safety
function pp() {
  u="+Ki+Mi+Gi+Ti+Pi+Ei";
  split(u,unit,"+");
  v=sum;
  for(i=1;i<7;i++) {
    if(v<1024) break;
    v/=1024;
  }
  printf("%.3f %sB\n", v, unit[i]);
}
{sum+=$5}
END{pp()}'

por exemplo:

$ ds ~        
72.891 GiB
    
por 03.06.2013 / 21:57
8

Algumas versões do du suportam o argumento --apparent-size para mostrar o tamanho aparente em vez do uso do disco. Então seu comando seria:

du -hs --apparent-size

Das páginas man do du incluídas no Ubuntu 12.04 LTS:

--apparent-size
      print apparent sizes,  rather  than  disk  usage;  although  the
      apparent  size is usually smaller, it may be larger due to holes
      in ('sparse') files, internal  fragmentation,  indirect  blocks,
      and the like
    
por 23.06.2013 / 09:24
4

Apenas uma alternativa, usando ls :

ls -nR | grep -v '^d' | awk '{total += $5} END {print total, "Total"}'

ls -nR : -n como -l , mas liste os subdiretórios numéricos UIDs e GIDs e -R list de forma recursiva.

grep -v: Inverte o sentido de correspondência para selecionar linhas não correspondentes. (-v é especificado por POSIX.). '^ d' excluirá os diretórios.

Comando Ls: link

Man Grep: link

EDITAR :

Editado como sugestão @ Sergey Vlasov.

    
por 03.06.2013 / 00:17
4

Supondo que você tenha du do GNU coreutils, este comando deve calcular o tamanho aparente total do número arbitrário de arquivos regulares dentro de um diretório, sem nenhum limite arbitrário no número de arquivos:

find . -type f -print0 | du -scb --files0-from=- | tail -n 1

Adicione a opção -l a du se houver alguns arquivos com hardlink dentro, e você quiser contar cada hardlink separadamente (por padrão, du contará vários hardlinks apenas uma vez).

A diferença mais importante com o du -sb simples é que a% recursivadu também conta os tamanhos dos diretórios, que são reportados de forma diferente por diferentes sistemas de arquivos; para evitar isso, o comando find é usado para transmitir apenas arquivos regulares para du . Outra diferença é que os links simbólicos são ignorados (se eles devem ser contados, o comando find deve ser ajustado).

Esse comando também consumirá mais memória do que o du -sb , porque usar o --files0-from=FILE faz du armazenar números de dispositivos e inode de todos arquivos processados, em oposição ao comportamento padrão de lembrando apenas arquivos com mais de um link físico. (Isso não é um problema se a opção -l for usada para contar hardlinks várias vezes, porque o único motivo para armazenar os números de dispositivo e inode é ignorar os arquivos com link físico que já haviam sido processados.)

Se você deseja obter uma representação legível do tamanho total, basta adicionar a opção -h (isso funciona porque du é invocado apenas uma vez e calcula o tamanho total, ao contrário de outras respostas sugeridas):

find . -type f -print0 | du -scbh --files0-from=- | tail -n 1

ou (se você estiver preocupado que alguns efeitos de -b sejam substituídos por -h )

find . -type f -print0 | du -sc --apparent-size -h --files0-from=- | tail -n 1
    
por 02.06.2013 / 22:26
3

Se tudo o que você quer é o tamanho dos arquivos, excluindo o espaço ocupado pelos diretórios, você pode fazer algo como

find . -type f -print0 | xargs -0 du -scb | tail -n 1

@SergeyVlasov apontou que isso falhará se você tiver mais arquivos do que argmax . Para evitar que você possa usar algo como:

find . -type f -exec du -sb '{}' \; | gawk '{k+=$1}END{print k}'
    
por 02.06.2013 / 18:57