df -h는 정확히 어떻게 작동합니까? 를 실행하면 df
다음과 같은 결과를 얻습니다.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/simfs 41943040 7659828 34283212 19% /
를 실행하면 df -h
다음과 같은 결과를 얻습니다.
Filesystem Size Used Avail Use% Mounted on
/dev/simfs 40G 7.4G 33G 19% /
문제는 같은 번호를 얻는 방법입니다.
41943040 / 1024 / 1024 = 40 자, 나머지를 1024로 나누자.
7659828 / 1024 / 1024 = 7,304981
그럼 아마도 1000?
7659828 / 1000 / 1000 = 7,659828
df -h
7.4G는 어떻게 탄생했나요?
34283212 / 1024 / 1024 = 32,695, which is ±33G
df는 오픈 소스이지만복제됨재구매하고 코드를 확인했습니다. 이것이 내가 찾은 것입니다:
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));
}
나는 이 언어에 대한 경험이 없지만 내가 이해한 바에 따르면 각 열의 값이 1024 또는 1000으로 나눌 수 있는지 확인하고 옵션 값을 렌더링하기 위해 더 나은 것을 선택합니다 -h
. 하지만 1000이나 1024로 나누어도 같은 값이 나오지 않습니다. 왜?
왜 그런지 알 것 같아요. 1000 또는 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;
그럼 7659828 / 1024 / 1024 = 7,304981을 해독해 보겠습니다. -h
대답을 주었다7.4G
7659828 / 1024 = 7480,xxx
7659828 / 1000 = 7659,xxx
7659는 7480을 1024로 나눈 값입니다.
숫자는 여전히 엄청납니다. 계속해 보겠습니다.
7659828 / 1024 / 1024 = 7,xxx (7,3049..)
7659828 / 1024 / 1000 = 7,xxx (7,4803..)
이제 1000이 필요하고 7,48이 주어지면믿다코드 어딘가에 "많은 것보다 적게 말하는 것이 낫다"고 반올림되어 7.4G의 데이터를 넣을 수 있지만 7.5G는 넣을 수 없습니다.
33.4G도 상황은 마찬가지
34283212 / 1024 / 1000 = 33.47...
그래서 33G가 되었습니다.
답변1
게시한 코드는 첫 번째 줄에 텍스트를 생성하는 "get_header" 함수에서 가져온 것입니다. 귀하의 경우 이는 "1K-blocks" 헤더에 적용됩니다( df -B1023
차이점을 확인하려면 호출하세요).
참고: "1K"는 1000바이트 블록이 아닌 1024바이트 블록을 나타냅니다("1kB 블록"으로 표시됨, 참조 df -B1000
).
사람이 읽을 수 있는 형식의 숫자 계산은 "human_read"(human.c:153) 함수에 의해 처리됩니다. df.c:1571에서 다음 플래그를 사용하여 호출할 때 사용되는 옵션을 찾을 수 있습니다 -h
.
case 'h':
human_output_opts = human_autoscale | human_SI | human_base_1024;
output_block_size = 1;
break;
모든 계산은 사람이 읽을 수 있는 형식("-h")의 기본 1024에서 수행됩니다. 표시된 human_output_opts 외에도 여기에 적용되는 기본 설정이 있습니다(human.h, 열거형 선언 참조).
/* 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,
human_output_opts에는 human_round_to_nearest 또는 human_floor가 포함되어 있지 않으므로 기본값인 human_ceiling을 사용합니다. 따라서 계산된 값은 모두 반올림됩니다.
설정을 확인하기 위해 다음 1K 청크를 기반으로 사람이 읽을 수 있는 형식을 계산해 볼 수 있습니다 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
이는 와 동일한 출력입니다 df -h
.
(...1000바이트 형식을 선호하는 경우 간단히 호출할 수 있습니다 df -H
).
답변2
df
df -h
원본 소스 인 FreeBSD 프로그램 이나 Solaris 구현 모두 df
이 작업을 수행하지 않습니다.
Solaris 소스는 OpenSource이므로 df
운영 체제에서 컴파일되는지 확인할 수 있습니다.