Кількість байтів "ls -l <випадковий файл>" порівняно з "wc -c <випадковий файл>"


25

Чи можлива ситуація, коли

ls -l file.txt

показує не таку кількість байтів, як

wc -c file.txt

В одному сценарії я знайшов порівняння цих двох значень. Що може бути причиною цього? Чи навіть можливо мати різні підрахунки байтів одного файлу?


2
Чи можете ви дати якийсь контекст цьому сценарію, який ви знайшли?
Kusalananda

Відповіді:


13

Так, бувають такі випадки.

У разі посилань на Linux із системою GNU ls, ls -lволю видасть розмір посилання, при wc -cцьому вирішить фактичний файл та прочитає там кількість байтів. Нижче ви бачите, що ls -lповідомляє 29 байт, а wc172 байти у фактичному файлі.

$ ls -l /etc/resolv.conf                                                                                                 
lrwxrwxrwx 1 root root 29 1月  17  2016 /etc/resolv.conf -> ../run/resolvconf/resolv.conf
$ wc -c /etc/resolv.conf                                                                                                 
172 /etc/resolv.conf
$ wc -c /var/run/resolvconf/resolv.conf                                                                                  
172 /var/run/resolvconf/resolv.conf
$ ls -l /var/run/resolvconf/resolv.conf                                                                                  
-rw-r--r-- 1 root root 172 1月  15 15:49 /var/run/resolvconf/resolv.conf

У випадку віртуальних файлових систем , таких як/proc або /sys, багато файлів відображатимуться як розмір 0 ls -l. Під /devфайловою системою ми маємо різноманітні спеціальні файли, такі як символьні пристрої та блокові пристрої - wc -cвисить на них і ls -lпоказує основні та незначні числа замість розміру.

Іменовані труби будуть повідомлятися як 0байти ls -c, але wc -cфактично будуть читати вміст труби, тому технічно він скаже вам, скільки даних міститься в названій трубі:

$ mkfifo named.pipe                                                                                                      
$ echo "This is a test" > named.pipe &
[1] 2129
$ ls -l named.pipe
prw-rw-r-- 1 xieerqi xieerqi 0 1月  16 08:40 named.pipe|
$ wc -c named.pipe
15 named.pipe
[1] + Done                 echo "This is a test" >named.pipe 

Для звичайних файлів розмір повинен бути рівним.


Сенс ls -lі wc -c, і як вони працюють також відрізняється. wc -cнасправді відкривається файл для читання (ви можете побачити це, якщо, наприклад, запустите strace wc -c /etc/passwd). ls -lвиконує stat()дзвінок лише з тих. Це також пояснює, чому в /proc ls -lшоу 0 розмір - ви не можете статистика цих файлів, оскільки вони не "справжні" або фактично зберігаються на жорсткому диску / ssd. wc -cнатомість читає вміст цього файлу та обчислює його розмір.

Нарешті, ls -lце лише інструмент для інтерактивного переліку елементів. Це рідко підходить для сценаріїв. Коли вам справді потрібно прочитати дані, скористайтеся wc -cнатомість.

Зауважте, що сценарій та оцінка розміру файлу ls- не найкращий кандидат. Насправді, це одна з поширених практик уникнути розбору lsрезультатів . Будь ласка, використовуйте du -b для з’ясування розміру файлу.


1
Невелике уточнення - віртуальні файли (в /sys/, /proc/тощо) можуть надавати statінформацію, якщо реалізатор захоче. Здебільшого це не є вагомою причиною, тому це опущено. Приклади включають, /proc/kcoreщо повідомляється як розмір пам'яті ядра, що адресоване (зазвичай набагато більше, ніж наявна фізична пам'ять).
Toby Speight

11

ls -l поверне розмір файлу, про який повідомляє файлова система.

wc -cспробує прочитати файл, щоб визначити "фактичний" розмір. З моїх спостережень, схоже, спершу намагаюся шукати до кінця, і якщо це не спрацює, він зчитує весь файл, рахуючи розмір, який він проходить.

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

lsдасть неправильний вихід для певних файлових систем. Наприклад, віртуалізовані файлові системи, як-от /proc, повідомлять розмір нуля для багатьох файлів, оскільки ці "файли" фізично ніде не зберігаються; вони генеруються відповідно до вимог програмного забезпечення.

wcне працюватиме на всіх для файлів без дозволу на читання, а lsвимагають дозволів тільки для відображення каталогу (порівняйте ls -l /etc/shadowз wc -c /etc/shadow).

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

Я впевнений, що є інші відмінності, про які я ще не думав, але я подумав, що я дам чітке і просте пояснення щодо основної причини цих відмінностей.


+1 для згадування дозволів для читання та seek(). Це, мабуть, так, після запуску strace wc -lдекількох великих файлів.
Сергій Колодяжний

+1 за додавання набагато більше деталей, ніж моя відповідь!
Cyclic3

6

Для звичайного файлу ls та wc стат. Однак для файлу / proc або / sys, ls повертає 0, але wc повертає інше число:

$ ls -l /proc/modules
-r--r--r--  1 root root 0 Jan 16 14:56 modules
                        ^ this one
$ wc -c /proc/modules
7621 modules

Це, мабуть, якийсь спосіб з’ясувати, чи є щось спеціальним файлом.


2
wc -cдля мене принаймні дзвонить fstat, але, здавалося б, для інших цілей. Він знаходить довжину файлу, lseekвідкладаючи його до кінця. Якщо це поверне помилку, це readвесь файл.
Мюзер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.