Почему отчет о размере каталогов отличается от других файлов?

Используя compgen определенно хороший. С другой стороны, и это работало бы с любой оболочкой POSIX, Вы могли регистрировать команды $PATH с:

(IFS=:; set -f; ls -- $PATH | grep top$)

С zsh:

type -m '*top'

Можно также запросить whatis базу данных:

man -ks1:8 top$
8
13.04.2017, 15:37
3 ответа

Я думаю причина вашего замешательства в том, что вы не знаете, что такое каталог . Для этого давайте сделаем шаг назад и посмотрим, как работают файловые системы Unix.

Файловая система Unix имеет несколько отдельных понятий для адресации данных на диске:

  • блоки данных - это группа блоков на диске, которые имеют содержимое файл.
  • inodes - это специальные блоки в файловой системе с числовым адресом, уникальным в этой файловой системе, который содержит метаданные о файле, такие как:
    • разрешения
    • доступ / модификация раз
    • размер
    • указатели на блоки данных (может быть список блоков, экстентов и т. д.)
  • имена файлов - это иерархические местоположения в корне файловой системы, которые отображаются на индексные дескрипторы.

Другими словами, «файл» на самом деле состоит из трех разных вещей:

  1. ПУТЬ в файловой системе
  2. индексный дескриптор с метаданными
  3. блоки данных, на которые указывает индексный дескриптор

Большая часть время, пользователи воображают, что файл является синонимом «сущности, связанной с именем файла» - это только тогда, когда вы имеете дело с низкоуровневыми сущностями или API файла / сокета, которые вы думаете об индексных дескрипторах или блоках данных. Каталоги - одна из таких низкоуровневых сущностей.

Вы можете подумать, что каталог - это файл, содержащий множество других файлов. Это правильно только наполовину. Каталог - это файл, который сопоставляет имена файлов с номерами inode. Он не «содержит» файлы, а указывает на имена файлов. Думайте об этом как о текстовом файле, который содержит такие записи:

  • . - inode 1234
  • .. - inode 200
  • Документы - inode 2008
  • README.txt - inode 2009

Вышеупомянутые записи называются записями каталога . Это в основном сопоставления имен файлов с номерами inode. Каталог - это специальный файл, содержащий записи каталога.

Это, конечно, упрощение, но оно объясняет основную идею и другие странности каталогов.

  • Почему каталогам не известен свой размер?
    • Поскольку они содержат только указатели на другие материалы, вам нужно перебирать их содержимое, чтобы найти размер
  • Почему каталоги никогда не пусты?
    • Потому что они содержат как минимум расширение. и .. записи. Таким образом, правильный каталог будет по крайней мере таким же маленьким, как наименьший размер файла, который может содержать эти записи. В большинстве файловых систем самый маленький размер - 4096 байт.
  • Почему вам нужно разрешение на запись в родительский каталог при переименовании файла?
    • Поскольку вы не просто изменяете файл, вы меняете запись в каталоге указывая на файл.
  • Почему ls показывает странное количество «ссылок» на каталог?
    • каталог может ссылаться (связываться) сам с собой, с его родителем, со своими дочерними элементами.
  • Что делает жесткая ссылка и чем она отличается от символической?
    • жесткая ссылка добавляет запись каталога , указывающую на тот же номер inode . Поскольку он указывает на номер inode, он может указывать только на файлы в той же файловой системе (inodes являются локальными для файловой системы)
    • , символическая ссылка добавляет новый inode, который указывает на отдельное имя файла. Поскольку он ссылается на имя файла, он может указывать на произвольные файлы в дереве.

Но подождите! Происходят странные вещи!

ls -ld somedirectory всегда показывает размер файла 4096, тогда как ls -l somefile показывает фактический размер файла. Почему?

Проблема 1: когда мы говорим «размер», мы можем иметь в виду две вещи:

  • размер файла, который представляет собой число, хранящееся в индексном дескрипторе; и
  • выделенный размер, который представляет собой количество блоков, связанных с индексным дескриптором, умноженное на размер каждого блока.

Обычно это не одно и то же число. Попробуйте запустить stat в обычном файле, и вы увидите разницу.

Когда файловая система создает непустой файл, она обычно охотно распределяет блоки данных по группам. Это связано с тем, что файлы имеют тенденцию произвольно быстро увеличиваться и уменьшаться.Если файловая система выделяет столько блоков данных, сколько необходимо для представления файла, рост / сжатие будет медленнее, а фрагментация станет серьезной проблемой. Таким образом, на практике файловым системам не нужно постоянно перераспределять пространство для небольших изменений. Это означает, что на диске может быть много места, которое «занято» файлами, но полностью не используется.

Что делает файловая система со всем этим неиспользуемым пространством? Ничего такого. Пока не почувствуете, что это нужно.Если ваш инструмент оптимизатора файловой системы - возможно, онлайн-оптимизатор, работающий в фоновом режиме, возможно, часть вашего fsck, возможно, встроенный в вашу файловую систему - кажется, что он может переназначить блоки данных ваших файлов - перемещение использованных блоков, освобождение неиспользуемых блоки и т. д.

Итак, теперь мы подошли к разнице между обычными файлами и каталогами: поскольку каталоги составляют «основу» вашей файловой системы, вы ожидаете, что к ним может потребоваться частый доступ или изменение, и поэтому их следует оптимизировать. И поэтому вы вообще не хотите, чтобы они были фрагментированы. Когда каталоги создаются, они всегда максимизируют все свои блоки данных по размеру, даже если у них есть только определенное количество записей каталога. Это нормально для каталогов, потому что, в отличие от файлов, каталоги обычно ограничены по размеру и скорости роста.

Сообщенный размер каталогов 4096 - это номер «файла», хранящийся в индексном дескрипторе каталога, а не количество записей в каталоге. Это не фиксированное число - это максимальное количество байтов, которое уместится в выделенное количество блоков для каталога. Обычно это 512 байт / блок, умноженное на 8 блоков, выделенных для файла с любым содержимым - кстати, для каталогов размер файла и выделенный размер одинаковы. Поскольку он выделен как единая группа, оптимизатор файловой системы не будет перемещать свои блоки.

По мере роста каталога ему назначается больше блоков данных, и он также будет максимально этих блоков путем соответствующей корректировки размера файла.

Итак, ls и stat покажут поле размера файла inode каталога, которое установлено равным размеру назначенных ему блоков данных.

11
27.01.2020, 20:09

две проблемы

PS1 устанавливается один раз, необходимо повторно установить после изменения имени хоста.

Вы можете отредактировать сценарий с помощью

export PS1='[\u@'$(hostname)' \W]\$' 

в конце, но сценарий должен быть запущен как

. ./changehost newhostname

отметить ведущую точку.

Если не использовать ведущую точку, PS1 будет установлен в новую временную оболочку и потерян.


Неясно, будет ли значение bash update hostname (username) (сохраненное в/h ,/u) после его выполнения, поскольку это значение вряд ли изменится.

Тем не менее, позаботьтесь о PATH.

-121--37829-

Очевидно, KDE начал использовать DBus только после версии 4. Предыдущие версии использовали dcop, и существуют эквивалентные способы завершения сеанса dekstop с ним:

DISPLAY=:0 dcop ksmserver ksmserver logout 0 0 0
-121--243496-

Я думаю, что начальный, пустой, размер каталога зависит от файловой системы. В файловых системах ext3 и ext4, к которым у меня есть доступ, я также получаю 4096-байтовые пустые каталоги. На сетевом накопителе, подключенном к NFS, я получаю 80-байтовый пустой каталог. У меня нет доступа к файловой системе ReiserFS, новый, пустой размер каталога будет интересен.

Традиционно каталог представлял собой файл с битовым набором в его inode (структура на диске, описывающая файл), который указывал, что он является каталогом. Этот файл был заполнен записями переменной длины. Вот что говорит /usr/include/linux/dirent.h :

struct dirent64 {
    __u64       d_ino;
    __s64       d_off;
    unsigned short  d_reclen;
    unsigned char   d_type;
    char        d_name[256];
};

Вы можете пропустить записи каталога-файла, используя значения d _ off . Если запись была удалена ( unlink () системный вызов, используемый командой rm ), значение d _ off предыдущей записи было увеличено для учета отсутствующей записи. Ничто не делало «уплотнения» записей. Вероятно, было просто показать распределение по количеству байтов в дисковых блоках, выделенных файлу, вместо того, чтобы пытаться выяснить, сколько байтов в файле каталога приходится на все записи или только на последнюю запись.

В настоящее время каталоги имеют внутренние форматы, такие как B-деревья или хэш-деревья . Я предполагаю, что это либо большое улучшение производительности, чтобы сделать каталоги блоками, или есть «пустой космос» внутри них, как старые школьные каталоги, так что трудно решить, что «реальный размер» в байтах каталога, особенно тот, который используется в течение некоторого времени, и файлы были удалены и добавлены в него много. Проще просто показать количество блоков, умноженное на байты на блок.

3
27.01.2020, 20:09

Файл может не иметь выделенных блоков; флаг -s на ls покажет это различие, в то время как для каталога будет выделено некоторое количество минимальных блоков, следовательно, размер по умолчанию. (Если только вы не используете какую-то модную современную файловую систему, которая выкидывает эти понятия из окна.) Например:

% mkdir testfoo
% cd testfoo/
% mkdir foodir
% touch foofile
% ln -s foofile foosln
% ls -ld foo*
drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
-rw-rw-r--  1 jmates  jmates    0 Oct  5 19:48 foofile
lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
% ls -lds foo*
8 drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
0 -rw-rw-r--  1 jmates  jmates    0 Oct  5 19:48 foofile
0 lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
% 

Обратите внимание, что символическая ссылка здесь не принимает блоков, несмотря на выделение семи байтов для деталей, необходимых для readlink (2) , как любопытно! В любом случае, давайте теперь добавим в foofile один или два байта:

% echo >> foofile a
% ls -lds foo*
8 drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
8 -rw-rw-r--  1 jmates  jmates    2 Oct  5 19:49 foofile
0 lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
%

И можно увидеть, что выделенные блоки для foofile переместились на 8 , несмотря на то, что только два байта (прикреплены a и новая строка echo ).

Файлы также могут быть разреженными, что является еще одним фактором, по которому сообщаемый размер файла может отличаться от фактического содержимого, в зависимости от того, как инструмент, взаимодействующий с файлом, обрабатывает эту разреженность.

Кроме того, размер каталога можно увеличить, создать много файлов с очень длинными именами и проверить, что происходит с размером каталога (и с выделенными блоками) после создания каждого нового длинного имени файла с помощью ls -lds.

2
27.01.2020, 20:09

Теги

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