Вопрос или проблема
Я использую эти команды:
du -sh --apparent-size ./*
du -sh ./*
оба показывают:
4.0K ./Lightroom_catalog_from_win_backup
432M ./Lightroom catalog - wine_backup
в то время как эти каталоги содержат:
$ll ./"Lightroom catalog - wine_backup"
total 432M
-rwxrwx--- 1 gigi gigi 432M Mar 18 2018 Lightroom 5 Catalog Linux.lrcat
-rwxrwx--- 1 gigi gigi 227 Nov 21 2015 zbackup.bat
$ll ./Lightroom_catalog_from_win_backup
total 396M
-rwxrwx--- 3 gigi gigi 396M Dec 17 09:35 Lightroom 5 Catalog Linux.lrcat
-rwxrwx--- 3 gigi gigi 227 Dec 17 09:35 zbackup.bat
Почему du
показывает 4.0K
для ./Lightroom_catalog_from_win_backup и как я могу заставить его отображать правильно?
PS: другая системная информация:
$stat --file-system $HOME
File: "/home/gigi"
ID: 5b052c62a5a527bb Namelen: 255 Type: ext2/ext3
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 720651086 Free: 155672577 Available: 119098665
Inodes: Total: 183050240 Free: 178896289
$lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
Я могу воспроизвести, если файлы являются жесткими ссылками:
~ mkdir foo bar
~ dd if=/dev/urandom of=bar/file1 count=1k bs=1k
1024+0 записей в
1024+0 записей из
1048576 байт (1.0 MB, 1.0 MiB) копировано, 0.00985276 с, 106 MB/c
~ ln bar/file1 foo/file1
~ du -sh --apparent-size foo bar
1.1M foo
4.0K bar
Это ожидаемое поведение. Из документации GNU du
:
Если два или более жестких ссылок указывают на один и тот же файл, будет учтена только одна из жестких ссылок. Порядок аргументов файла влияет на то, какие ссылки учитываются, и изменение порядка аргументов может изменить числа и записи, которые выводит du.
Если вам действительно нужно несколько размеров жестких ссылок, попробуйте параметр -l
:
‘
-l
’
‘--count-links
’
Учитывать размер всех файлов, даже если они уже появились (как жесткая ссылка).
~ du -sh --apparent-size foo bar -l
1.1M foo
1.1M bar
Обратите внимание, что количество ссылок 3
для двух файлов Lightroom 5 Catalog Linux.lrcat
и zbackup.bat
в Lightroom_catalog_from_win_backup
.
Это означает, что эти два файла жестко связаны с (дополнительными именами для) других файлов где-то. Когда вы запускаете du
на каталоге или наборе файлов, каждая жесткая ссылка учитывается только один раз.
Пример:
$ ls -l
total 41024
-rw-r--r-- 2 kk wheel 10485760 Dec 17 09:07 file1
-rw-r--r-- 2 kk wheel 10485760 Dec 17 09:07 file2
$ du -h file1
10.0M file1
$ du -h file2
10.0M file2
$ du -h .
10.0M .
Это поведение прямо предписано стандартом POSIX для утилиты du
:
Файл, который встречается несколько раз под одним операндом файла и имеет количество ссылок больше 1, должен учитываться и записываться только для одной записи.
Некоторые реализации du
имеют нестандартные параметры для отключения этого поведения. Для GNU du
это делается с помощью параметра -l
.
Скорее всего, это работает правильно. du
учитывает каждый файл только один раз, независимо от того, сколько раз он упоминается. Вероятно, что ваши два каталога содержат один и тот же набор жестко связанных файлов.
Страница man для GNU du
предлагает -l
, --count-links
, чтобы отключить эту стандартную оптимизацию (см. man du
, чтобы проверить, включает ли ваша реализация это). Или вы можете запустить du
дважды, один раз для каждого каталога.
Ответ или решение
Почему команда du
неправильно отображает размер каталога
Введение
Когда вы работаете с командой du
(disk usage), вы можете столкнуться с ситуацией, когда размер, отображаемый для каталогов, не соответствует вашим ожиданиям. В данном случае, команда возвращает 4.0K для каталога ./Lightroom_catalog_from_win_backup
, хотя фактически он содержит файлы общим размером около 396M. Разберем, почему это происходит и как это исправить.
Причина проблемы
Как выясняется, это связано с тем, что в каталогах используются жесткие ссылки. Ваша команда du
по умолчанию считает размер каждого файла только один раз, даже если он содержится в нескольких каталогах. Это происходит из-за того, что жесткие ссылки указывают на один и тот же инод на диске.
Почему это важно?
Каждый файл в Unix-подобных системах с жесткими ссылками имеет определенное количество ссылок, и команда du
игнорирует дополнительные ссылки при подсчете размера, так как они указывают на один и тот же набор данных. В вашем случае, файлы внутри ./Lightroom_catalog_from_win_backup
имеют счетчик ссылок, равный 3:
-rwxrwx--- 3 gigi gigi 396M
Это означает, что данный файл имеет ещё две жесткие ссылки на него в других местах файловой системы, и du
считает его только один раз.
Как это исправить
Если вам необходимо получить размер всех файлов, даже тех, которые имеют жесткие ссылки, вы можете использовать опцию -l
или --count-links
. Эта опция заставляет du
учитывать все ссылки на файл. Пример команды:
du -sh --apparent-size -l ./*
Используя эту опцию, вы получите ожидаемые размеры для всех каталогов, даже если некоторые из них содержат жесткие ссылки на файлы.
Примеры
Как вы уже отметили в ваших тестах, с использованием жестких ссылок результат выглядит так:
du -sh --apparent-size foo bar -l
1.1M foo
1.1M bar
Это показывает, что теперь размеры обоих каталогов учитываются корректно, без игнорирования жестких ссылок.
Заключение
Таким образом, причина, по которой команда du
неправильно отображает размер каталога, связана с тем, что жесткие ссылки на файлы учитываются только один раз. Чтобы получить корректные данные, необходимо использовать опцию -l
для учета всех ссылок. Это важно, особенно при управлении файлами и каталогами с жесткими ссылками, чтобы избежать недопонимания при анализе использования дискового пространства.
Для более глубокого понимания команды du
и других её опций, всегда можно обратиться к документации:
man du
Это даст вам возможность лучше ориентироваться в использовании команды и её функционале.