Есть ли возможная ситуация, когда
ls -l file.txt
показывает не такое количество байтов, как
wc -c file.txt
В одном скрипте я нашел сравнение этих двух значений. Что может быть причиной этого? Можно ли даже иметь разные количества байтов в одном и том же файле?
Ответы:
Да, есть такие случаи.
В случае символьных ссылок в системе Linux с GNU
ls
, онls -l
выдаст размер ссылки, аwc -c
также разрешит фактический файл и прочитает количество байтов там. Ниже вы можете видеть, чтоls -l
сообщает 29 байтов, аwc
сообщает 172 байта в реальном файле.В случае виртуальных файловых систем , таких как
/proc
или/sys
, многие файлы там будут иметь размер 0ls -l
. Под/dev
файловой системой у нас есть множество специальных файлов, таких как символьные устройства и блочные устройства - ониwc -c
подвешены на них иls -l
показывают большие и младшие числа вместо размера.Именованные каналы будут сообщаться как
0
байтыls -c
, но наwc -c
самом деле будут читать содержимое канала, поэтому технически он скажет вам, сколько данных находится в именованном канале:Для обычных файлов размер должен быть одинаковым.
Суть
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 вызывают stat. Однако для файла / proc или / sys ls возвращает 0, а wc возвращает другое число:
Это, вероятно, какой-то способ узнать, является ли что-то специальным файлом.
источник
wc -c
для меня, по крайней мере, звонитfstat
, но, похоже, для других целей. Он находит длину файлаlseek
до конца. В случае, если это возвращает ошибку, этоread
весь файл.