Чому ls -l видає інший розмір від ls -s?


38

Я не можу зрозуміти, чому я отримую такі результати:

ls -l повідомляє мені, що розмір файлу (ІСТОРІЯ) становить "581944":

$ ls -l HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

ls -s каже, що це "572":

$ ls -s HISTORY
572 HISTORY

Мені, очевидно, потрібно, щоб значення використовували порівняльну шкалу. Тому спочатку я підтверджую, що використання --block-size 1в ls -lмені дає такий же результат, як і раніше:

$ ls -l --block-size 1 HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 581944 Feb 22 10:59 HISTORY

Тоді я роблю те саме, щоб ls -sотримати значення в тій же шкалі:

$ ls -s --block-size 1 HISTORY 
585728 HISTORY

Різні результати! 581944 ≠ 585728 .

Я намагався генерувати порівнянні значення навпаки, використовуючи -k, але отримую:

$ ls -lk HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 569 Feb 22 10:59 HISTORY
$ ls -sk HISTORY 
572 HISTORY

Знову різні результати, 569 ≠ 572 .

Я спробував вказати --si, щоб переконатися, що обидва варіанти використовували однаковий масштаб, безрезультатно:

$ ls -lk --si HISTORY 
-rw-rw-r-- 1 waldyrious waldyrious 582k Feb 22 10:59 HISTORY
$ ls -sk --si HISTORY 
586k HISTORY

... знову ж таки, різні значення: 582k ≠ 586k .

Я спробував здійснити пошук в Інтернеті, але єдине, що могло знайти, що здалося актуальним, це :

Деякі файли мають "дірки" в них, так що використання, перераховане ls -s(...), менше розміру файлу, перерахованого ls -l. "

(зауважте, що в моїх результатах відбувається навпаки: ls -sповертає розміри більше, ніж ls -lменші.)

Тим часом на цій сторінці йдеться про це

немає елегантного способу виявлення отворів у файлі Unix.

Отже, як я можу впоратися з цією невідповідністю? Яке з цих значень можна вважати правильним? Чи може це бути помилка ls?

Відповіді:


47

Коротка відповідь:

  • ls -l дає розмір файлу (= кількість даних, які він містить)
  • ls -s --block-size 1 дає розмір файлу у файловій системі

Створимо два файли:

Розріджений файл 128 байт довжини (розріджений файл являє собою файл , що містить порожні блоки, см розрідженого файлу ):

# truncate -s 128 f_zeroes.img
# hexdump -vC f_zeroes.img 
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080

Ще один файл із випадковими даними, також розміром 128 байт:

# dd if=/dev/urandom of=f_random.img bs=1 count=128
# hexdump -vC f_random.img 
00000000  bc 82 9c 40 04 e3 0c 23  e6 76 79 2f 95 d4 0e 45  |...@...#.vy/...E|
00000010  19 c6 53 fc 65 83 f8 58  0a f7 0e 8f d6 d6 f8 b5  |..S.e..X........|
00000020  6c cf 1b 60 cb ef 06 c6  d0 99 c6 16 3f d3 95 02  |l..`........?...|
00000030  85 1e b7 80 27 93 27 92  d0 52 e8 72 54 25 4d 90  |....'.'..R.rT%M.|
00000040  11 59 a2 d9 0f 79 aa 23  2d 44 3d dd 8d 17 d9 36  |.Y...y.#-D=....6|
00000050  f5 ae 07 a8 c1 b4 cb e1  49 9e bc 62 1b 4f 17 53  |........I..b.O.S|
00000060  95 13 5a 1c 2a 7e 55 b9  69 a5 50 06 98 e7 71 83  |..Z.*~U.i.P...q.|
00000070  5a d0 82 ee 0b b3 91 82  ca 1d d0 ec 24 43 10 5d  |Z...........$C.]|
00000080

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

Тепер давайте розглянемо каталог:

# ls -ls --block-size 1 f_*
1024 -rw-r--r-- 1 user user 128 Mar 18 15:34 f_random.img
   0 -rw-r--r-- 1 user user 128 Mar 18 15:32 f_zeroes.img
   ^                         ^
   |                         |
Amount which the           Actual file size
files takes on the fs

Перше значення задається -s --block-size 1опцією, це кількість місця, що використовується файлом у файловій системі .

Як бачите, розріджений файл займає нульовий простір, оскільки файлова система ( ext3в даному випадку) була досить розумною, щоб визнати, що вона містить лише нулі. Також файл з випадковими даними займає 1024 байти на диску!

Значення залежить від того, як базова файлова система обробляє файли (розмір блоку, обмежена здатність файлу, ...).

У шостому стовпці розмір файлу, якби ви його прочитали - це обсяг даних, який містить файл, і це 128 байт для обох файлів!


1
Імовірно, навіть порожній файл або файл, заповнений нульовими значеннями, десь займе місце в таблиці розподілу файлів? Чому це не ls -sрахується?
Flimm

2
Метадані про файли зберігаються в inodes. Кожна файлова система має обмежену кількість входів, якими вона може користуватися. Щоб побачити, скільки вільних входів має файлова система та їх розмір: sudo tune2fs -l /dev/sdaX|grep Inodeабо df -iдля всіх розділів.
phoibos

1
Я тільки що знайшов цікавий, без штучного способу перевірити це: торрент .part файли здаються хорошими прикладами файлів з отворами: ls -lsh ~/Downloads/torrentsдає мені, наприклад, 92K -rw-r--r-- 1 waldir waldir 350M Sep 15 2012 video.avi.part. Тобто, 92K, повернене опцією -s, - це фактичний простір, який займає файл, файлова система, і 350M, повернута опцією -l, - це повний розмір, який має мати файл , якби він був повністю завантажений (тобто якщо всі байти, від початку до кінця, були не нульовими). Див. Списки.freebsd.org/pipermail
freebsd-

14

ls -sповідомляє вам розміщений розмір файлу, завжди кратний одиниці розподілу. ls -lповідомляє фактичний розмір. Простий спосіб тестування:

$ echo 1 > sizeTest
$ ls -l --block-size 1 sizeTest 
-rw-rw-r-- 1 g g 2 Mär 18 15:18 sizeTest
$ ls -s --block-size 1 sizeTest 
4096 sizeTest
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.