Почему общий размер блоков статистики для каталога в два раза больше размера блока ls для каталога?

Я довольно новичок в Ubuntu и хотел бы больше узнать о программировании на Linux.

Каждый раз, когда я печатаю ls -l и снова сравниваю его с моими собственными кодами, чтобы добавить st_blocks каждого файла, результатом всегда будет статический блок, вдвое превышающий ls размер блока?

Есть ли какое-то конкретное объяснение этому?


В командной строке:

$ ls -ls
total 28
4 ... test
20 ... test.c
4 ... test.txt

Запрограммировать суммирование не '.' files:

$ myls
total 56
8 ... test
40 ... test.c
8 ... test.txt

Извлечение кода, используемого в цикле:

...
    ...
        if (dirName[0] != '.') {
            blocksize += buf.st_blocks;
    }
    return blocksize;
...
1
задан 22 June 2020 в 08:53

1 ответ

stat

Размер блока, используемого в качестве единицы для st_blocks , всегда составляет 512 байт в системах, использующих ядро ​​Linux (которое включает в себя все GNU / Linux) системы, такие как Ubuntu). Это тот же размер в большинстве других Unix-подобных операционных систем.

Как Стивен Китт объясняет в своем ответе на Почему st_blocks всегда сообщается в 512-байтовых блоках? :

Размер блока зависит от реализации. В Linux это всегда 512 байт по историческим причинам; в частности, это был типичный размер сектора диска .

(выделено мной)

stat (2) перечисляет членов struct stat , который включает:

blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

Команда stat (см. stat (1) ) также использует размер блока 512 байт. Например, как показано в ls -l , в моей системе / bin / nano имеет размер 208480 байт, а вывод stat / bin / nano включает в себя Blocks: 408 .


ls

ls -l по умолчанию печатает размеры файлов в байтах, но ls -s печатает их в блоках по 1024 байта. Существуют реализации ls для некоторых Unix-подобных систем, которые по умолчанию используют блоки по 512 байт, но обе GNU ls (которые предоставляют / bin / ls в Ubuntu) и busybox ls (другая реализация ls в Ubuntu) по умолчанию используется для блоков размером 1024 байта. Вам не нужно передавать -k для такого поведения, хотя это может быть необходимо в некоторых других системах.

При печати размеров файлов в блоках, Ubuntu ' Команда s ls по умолчанию использует блоки размером 1024 байта, поскольку они более удобны. Вы можете изменить это с - размер блока , если хотите. На практике я считаю, что наиболее популярными подходами являются:

  • передача -l без -s для получения размера в байтах (который фактически равен размеру блока 1)
  • передача -l или -s с -h для печати более удобочитаемых размеров с единичными метками
  • , пропуск -s и с использованием значения по умолчанию 1024 байта

Некоторые утилиты GNU выводят 512-байтовые блоки при запуске в режиме совместимости с POSIX . du является особенно очевидным случаем; сравните вывод du / bin / nano с выводом POSIXLY_CORRECT = du / bin / nano . GNU ls также ведет себя так, когда передается -s , но вывод с -l , а не -s , а также с -h , без изменений. (Вывод без параметров, конечно, также не изменяется, поскольку он не печатает размер.)

В дополнение к поддержке - размер блока , GNU ls также учитывает некоторые другие переменные окружения, наиболее заметно BLOCK_SIZE . В отличие от POSIXLY_CORRECT , это влияет не только на ls -s , но также ls -l без -s . Если по какой-либо причине у вас установлено BLOCK_SIZE , но вы не хотите, чтобы оно использовалось, и вы хотите, чтобы ls -s вместо этого использовали 1024-байтовые блоки, передав -k с -s переопределит его.

Есть другие способы отрегулировать это, и некоторая тонкость связана, когда более чем один способ используется одновременно. Для быстрой информации см. Примеры ниже и ls (1) ( man ls ). Для получения полной информации прочитайте руководство GNU coreutils (которое также должно быть доступно локально: запустите info coreutils ), особенно раздел 2.3 Размер блока .


ls examples

Вот некоторые примеры для управления размером блока, показанные в ls .

ls -l печатает размеры в байтах:

$ ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

ls -s печатает размеры в 1024-байтовых блоках:

$ ls -s /bin/nano
204 /bin/nano

Добавление -h к любой из них печатает его в удобочитаемой форме:

$ ls -lh /bin/nano
-rwxr-xr-x 1 root root 204K Feb 15  2017 /bin/nano
$ ls -sh /bin/nano
204K /bin/nano

Передача -l и -s полагает, что -s покажет само по себе, вместо того, чтобы влиять на размер столбцов, создаваемых -l :

$ ls -ls /bin/nano
204 -rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano
$ ls -lsh /bin/nano
204K -rwxr-xr-x 1 root root 204K Feb 15  2017 /bin/nano

Добавление -k к командам, показанным выше, с помощью -s или -l не изменяет вывод, потому что GNU ls по умолчанию уже использует байтовые блоки 2014 с -s , а -l показывает размеры в байтах и ​​не зависит от - к . Однако -k оказывает влияние в более сложных ситуациях (см. Ниже).

Добавление - block-size = size-in-bytes приводит к тому, что размеры будут печатается в блоках указанного размера:

$ ls --block-size=256 -s /bin/nano
816 /bin/nano
$ ls --block-size=512 -s /bin/nano
408 /bin/nano
$ ls --block-size=1024 -s /bin/nano
204 /bin/nano

В отличие от некоторых других опций, опция - block-size оказывает этот эффект даже на столбец размера, созданный с помощью ls -l , который обычно указывается в байтах:

$ ls --block-size=256 -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ ls --block-size=512 -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ ls --block-size=1024 -l /bin/nano
-rwxr-xr-x 1 root root 204 Feb 15  2017 /bin/nano
$ ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

- размер блока не не переопределяется с помощью -k , даже если после него появляется -k :

$ ls -s --block-size=256 -k /bin/nano
816 /bin/nano
$ ls -s -k --block-size=256 /bin/nano
816 /bin/nano
$ ls -l --block-size=256 -k /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ ls -l -k --block-size=256 /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano

(Мои примеры использовать степени два, но операнд для - размер блока не должен быть степенью двойки. Также, -s и -l , очевидно, используют различные правила округления.)

Установка переменной среды BLOCK_SIZE имеет эффект, аналогичный передаче - размер блока :

$ BLOCK_SIZE=256 ls -s /bin/nano
816 /bin/nano
$ BLOCK_SIZE=512 ls -s /bin/nano
408 /bin/nano
$ BLOCK_SIZE=1024 ls -s /bin/nano
204 /bin/nano
$ BLOCK_SIZE=256 ls -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=512 ls -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=1024 ls -l /bin/nano
-rwxr-xr-x 1 root root 204 Feb 15  2017 /bin/nano

Разница в эффекте между - Опция -block-size и переменная окружения BLOCK_SIZE заключаются в том, что переменная окружения BLOCK_SIZE чаще всего переопределяется параметрами. -k переопределяет BLOCK_SIZE :

$ BLOCK_SIZE=256 ls -k -s /bin/nano
204 /bin/nano

Работает с -s . Но -k не переопределяет BLOCK_SIZE для размеров, отображаемых с помощью -l , просто потому, что (как описано выше) -k нет влияют на это:

$ BLOCK_SIZE=256 ls -k -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=256 ls -kls /bin/nano
204 -rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano

- размер блока также переопределяет BLOCK_SIZE . Поскольку - размер блока влияет как на -s , так и на -l , он переопределяет BLOCK_SIZE для обоих:

$ BLOCK_SIZE=256 ls --block-size=512 -s /bin/nano
408 /bin/nano
$ BLOCK_SIZE=256 ls --block-size=512 -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=256 ls --block-size=512 -ls /bin/nano
408 -rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano

Установка Переменная окружения POSIXLY_CORRECT , даже для пустой строки, заставляет ls -s использовать 512-байтовые блоки. Опции -h , -k и - размер блока переопределяют этот эффект, производя вместо них указанное поведение. Но в отличие от - размер блока и BLOCK_SIZE , ls -l по-прежнему печатает размеры в байтах.

$ POSIXLY_CORRECT= ls -s /bin/nano
408 /bin/nano
$ POSIXLY_CORRECT= ls -sh /bin/nano
204K /bin/nano
$ POSIXLY_CORRECT= ls -sk /bin/nano
204 /bin/nano
$ POSIXLY_CORRECT= ls --block-size=256 -s /bin/nano
816 /bin/nano
$ POSIXLY_CORRECT= ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

BLOCK_SIZE имеет приоритет над POSIXLY_CORRECT :

$ BLOCK_SIZE=256 POSIXLY_CORRECT= ls -s /bin/nano
816 /bin/nano

Опции, которые влияют на размер блока, также, конечно, имеют приоритет над POSIXLY_CORRECT , поскольку POSIXLY_CORRECT просто меняет размер блока по умолчанию. В частности, -k переопределяет POSIXLY_CORRECT :

$ POSIXLY_CORRECT= ls -s /bin/nano
408 /bin/nano
$ POSIXLY_CORRECT= ls -sk /bin/nano
204 /bin/nano

ls - другие параметры

Я не показал все комбинации соответствующих параметров и переменных среды.

Кроме того, есть еще две переменные окружения, связанные с тем, как GNU ls выбирает размеры блоков:

  • BLOCKSIZE (обратите внимание, что подчеркивания нет) ведет себя как BLOCK_SIZE для ls -s но не ls -l . Относится к BLOCK_SIZE , когда это присутствует.
  • LS_BLOCK_SIZE ведет себя как BLOCK_SIZE , но затрагивает только ls , но не du и df . Если оба параметра LS_BLOCK_SIZE и BLOCK_SIZE установлены, используется LS_BLOCK_SIZE .

Эти переменные среды, как и другие, имеют приоритет над POSIXLY_CORRECT [ ].

Как упомянуто выше, для получения дополнительной информации см. Раздел 2.3 Размер блока в руководстве GNU coreutils , включая подробности о них. Это руководство, которое вы можете прочитать из командной строки, набрав info coreutils , намного более детально, чем справочные страницы для ls и других команд, предоставляемых coreutils.

как и другие, имеет приоритет над POSIXLY_CORRECT .

Как упоминалось выше, см. раздел 2.3 Размер блока в руководстве GNU coreutils для получения дополнительной информации, включая подробности. на тех. Это руководство, которое вы можете прочитать из командной строки, набрав info coreutils , гораздо более детально, чем справочные страницы для ls и других команд, предоставляемых coreutils.

как и другие, имеет приоритет над POSIXLY_CORRECT .

Как упоминалось выше, см. раздел 2.3 Размер блока в руководстве GNU coreutils для получения дополнительной информации, включая подробности. на тех. Это руководство, которое вы можете прочитать из командной строки, набрав info coreutils , гораздо более детально, чем справочные страницы для ls и других команд, предоставляемых coreutils.

2
ответ дан 30 July 2020 в 22:22

Другие вопросы по тегам:

Похожие вопросы: