Чи можлива ситуація, коли
ls -l file.txt
показує не таку кількість байтів, як
wc -c file.txt
В одному сценарії я знайшов порівняння цих двох значень. Що може бути причиною цього? Чи навіть можливо мати різні підрахунки байтів одного файлу?
Чи можлива ситуація, коли
ls -l file.txt
показує не таку кількість байтів, як
wc -c file.txt
В одному сценарії я знайшов порівняння цих двох значень. Що може бути причиною цього? Чи навіть можливо мати різні підрахунки байтів одного файлу?
Відповіді:
Так, бувають такі випадки.
У разі посилань на 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 для з’ясування розміру файлу.
/sys/, /proc/тощо) можуть надавати statінформацію, якщо реалізатор захоче. Здебільшого це не є вагомою причиною, тому це опущено. Приклади включають, /proc/kcoreщо повідомляється як розмір пам'яті ядра, що адресоване (зазвичай набагато більше, ніж наявна фізична пам'ять).
ls -l поверне розмір файлу, про який повідомляє файлова система.
wc -cспробує прочитати файл, щоб визначити "фактичний" розмір. З моїх спостережень, схоже, спершу намагаюся шукати до кінця, і якщо це не спрацює, він зчитує весь файл, рахуючи розмір, який він проходить.
Це простий опис того, що два інструменти роблять, але це призводить до низки наслідків для результатів:
lsдасть неправильний вихід для певних файлових систем. Наприклад, віртуалізовані файлові системи, як-от /proc, повідомлять розмір нуля для багатьох файлів, оскільки ці "файли" фізично ніде не зберігаються; вони генеруються відповідно до вимог програмного забезпечення.
wcне працюватиме на всіх для файлів без дозволу на читання, а lsвимагають дозволів тільки для відображення каталогу (порівняйте ls -l /etc/shadowз wc -c /etc/shadow).
Як згадується в інших відповідях, поведінка для символічних посилань також відрізняється. Оскільки він wcнамагається їх прочитати, він закінчує читання файлу, на який вказує символьне посилання, тоді як, оскільки lsпросто запитує файлову систему, він повідомляє розмір, який використовується для зберігання символічного посилання.
Я впевнений, що є інші відмінності, про які я ще не думав, але я подумав, що я дам чітке і просте пояснення щодо основної причини цих відмінностей.
seek(). Це, мабуть, так, після запуску strace wc -lдекількох великих файлів.
Для звичайного файлу 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
Це, мабуть, якийсь спосіб з’ясувати, чи є щось спеціальним файлом.
wc -cдля мене принаймні дзвонить fstat, але, здавалося б, для інших цілей. Він знаходить довжину файлу, lseekвідкладаючи його до кінця. Якщо це поверне помилку, це readвесь файл.