AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 446999
Accepted
Lukas Liesis
Lukas Liesis
Asked: 2018-05-31 13:42:18 +0800 CST2018-05-31 13:42:18 +0800 CST 2018-05-31 13:42:18 +0800 CST

Por que df e df -h mostram valores diferentes? Como df -h executa o cálculo?

  • 772

como exatamente df -h funciona? Se eu executar df, recebo isto:

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/simfs      41943040 7659828  34283212  19% /

Se eu executar df -h, recebo isto:

Filesystem      Size  Used Avail Use% Mounted on
/dev/simfs       40G  7.4G   33G  19% /

A questão é como obter os mesmos números?

41943040 / 1024 / 1024 = 40 OK, vamos dividir os outros por 1024.

7659828 / 1024 / 1024 = 7,304981

Então talvez por 1000?

7659828 / 1000 / 1000 = 7,659828

Como df -hconseguiu 7.4G?

34283212 / 1024 / 1024 = 32,695, which is ±33G

Embora o df seja de código aberto, clonei o repositório e verifiquei o código. Isso é o que eu encontrei:

for (col = 0; col < ncolumns; col++)
    {
      char *cell = NULL;
      char const *header = _(columns[col]->caption);

      if (columns[col]->field == SIZE_FIELD
          && (header_mode == DEFAULT_MODE
              || (header_mode == OUTPUT_MODE
                  && !(human_output_opts & human_autoscale))))
        {
          char buf[LONGEST_HUMAN_READABLE + 1];

          int opts = (human_suppress_point_zero
                      | human_autoscale | human_SI
                      | (human_output_opts
                         & (human_group_digits | human_base_1024 | human_B)));

          /* Prefer the base that makes the human-readable value more exact,
             if there is a difference.  */

          uintmax_t q1000 = output_block_size;
          uintmax_t q1024 = output_block_size;
          bool divisible_by_1000;
          bool divisible_by_1024;

          do
            {
              divisible_by_1000 = q1000 % 1000 == 0;  q1000 /= 1000;
              divisible_by_1024 = q1024 % 1024 == 0;  q1024 /= 1024;
            }
          while (divisible_by_1000 & divisible_by_1024);

          if (divisible_by_1000 < divisible_by_1024)
            opts |= human_base_1024;
          if (divisible_by_1024 < divisible_by_1000)
            opts &= ~human_base_1024;
          if (! (opts & human_base_1024))
            opts |= human_B;

          char *num = human_readable (output_block_size, buf, opts, 1, 1);

          /* Reset the header back to the default in OUTPUT_MODE.  */
          header = _("blocks");

          /* TRANSLATORS: this is the "1K-blocks" header in "df" output.  */
          if (asprintf (&cell, _("%s-%s"), num, header) == -1)
            cell = NULL;
        }
      else if (header_mode == POSIX_MODE && columns[col]->field == SIZE_FIELD)
        {
          char buf[INT_BUFSIZE_BOUND (uintmax_t)];
          char *num = umaxtostr (output_block_size, buf);

          /* TRANSLATORS: this is the "1024-blocks" header in "df -P".  */
          if (asprintf (&cell, _("%s-%s"), num, header) == -1)
            cell = NULL;
        }
      else
        cell = strdup (header);

      if (!cell)
        xalloc_die ();

      hide_problematic_chars (cell);

      table[nrows - 1][col] = cell;

      columns[col]->width = MAX (columns[col]->width, mbswidth (cell, 0));
    }

Não tenho experiência com essa linguagem, mas pelo que entendi, ela tenta verificar se o valor de cada coluna é divisível por 1024 ou 1000 e escolhe o que for melhor para renderizar valores para a -hopção. Mas não obtenho o mesmo valor, não importa se divido por 1000 ou 1024. Por quê?

Acho que sei por quê. Ele verifica a divisão por 1000 ou 1024 em cada divisão.

          if (divisible_by_1000 < divisible_by_1024)
            opts |= human_base_1024;
          if (divisible_by_1024 < divisible_by_1000)
            opts &= ~human_base_1024;
          if (! (opts & human_base_1024))
            opts |= human_B;

então vamos quebrar 7659828/1024/1024 = 7,304981. -hdeu resposta de 7.4G

7659828 / 1024 = 7480,xxx
7659828 / 1000 = 7659,xxx

enquanto 7659 é maior que 7480, divida por 1024.

Ainda é um grande número, vamos continuar:

7659828 / 1024 / 1024 = 7,xxx  (7,3049..)
7659828 / 1024 / 1000 = 7,xxx  (7,4803..)

leva 1000 agora e dá 7,48 e acredito que em algum lugar do código ele arredonda para baixo, então "melhor dizer menos do que mais" enquanto você pode colocar 7,4 G de dados, mas não pode colocar 7,5 G.

Mesma história com 33.4G

34283212 / 1024 / 1000 = 33.47...

Portanto, torna-se 33G.

coreutils disk-usage
  • 2 2 respostas
  • 3407 Views

2 respostas

  • Voted
  1. Best Answer
    M2C8
    2018-06-01T02:49:39+08:002018-06-01T02:49:39+08:00

    O código que você postou é da função "get_header" que gera o texto da primeira linha. No seu caso, isso se aplica ao título "1K-blocks" (ligue df -B1023para ver a diferença).

    Nota importante: "1K" refere-se a blocos de 1024 bytes, não a blocos de 1000 bytes (indicado por "1kB-blocks", consulte df -B1000)

    O cálculo dos números no formato legível por humanos é tratado pela função "human_readable" (human.c:153). Em df.c:1571 você pode encontrar as opções que são usadas quando chamadas com o -hsinalizador:

    case 'h':
        human_output_opts = human_autoscale | human_SI | human_base_1024;
        output_block_size = 1;
        break;
    

    Todos os cálculos são feitos com base 1024 em formato legível por humanos ("-h"). Além dos human_output_opts mostrados, há uma configuração padrão que se aplica aqui (consulte human.h, declaração de enum):

    /* The following three options are mutually exclusive.  */
    /* Round to plus infinity (default).  */
    human_ceiling = 0,
    /* Round to nearest, ties to even.  */
    human_round_to_nearest = 1,
    /* Round to minus infinity.  */
    human_floor = 2,
    

    Como human_output_opts não inclui human_round_to_nearest ou human_floor, ele usará seu valor padrão de human_ceiling. Todos os valores calculados serão, portanto, arredondados.

    Para verificar as configurações, podemos tentar calcular o formato legível por humanos com base nos blocos de 1K de df:

    Size = ceil(41943040/1024/1024) = ceil(40) = 40
    Used = ceil(7659828/1024/1024) = ceil(7.305) = 7.4
    Available = ceil(34283212/1024/1024) = ceil(32.695) = 33
    

    Que é o mesmo que a saída de df -h.

    (... e se você preferir o formato de 1000 bytes, pode simplesmente chamar df -H).

    • 6
  2. schily
    2018-06-01T02:34:50+08:002018-06-01T02:34:50+08:00

    Nem o dfprograma do FreeBSD (de onde df -hvem originalmente) nem a dfimplementação do Solaris se comportam dessa maneira.

    Como as fontes do Solaris são OpenSource, você pode verificar se pode compilar dfem seu sistema operacional:

    • 0

relate perguntas

  • Como calcular o espaço total em disco usando df?

  • Erro de espaço em disco ao usar DD para gravar no disco bruto no leitor externo?

  • Como melhorar o uso do espaço em disco?

  • `du` legível por humanos com granulação mais fina

  • Outros motivos para "sem espaço no dispositivo" além da pasta totalmente usada?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve