Конечно, стандартным способом проверки, если файл пуст, является test -s FILE
один, но один из наших клиентов получил скрипт, содержащий такие тесты:
RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
echo "Badness: Log not empty"
exit 25
fi
с заявлениями поставщика о том, что он работает в двух средах, в которых они его тестировали. Само собой разумеется, что он потерпел неудачу в обоих двух местах, где я его тестировал.
Итак, мне стало любопытно. Когда ls -s
печатать 0
для пустых файлов?
Это мои выводы до сих пор:
- GFS в Linux: 4
- ext4 в Linux: 0
- ZFS на Солярисе: 1
- UFS на Солярисе: 0
- JFS в AIX: 0
- VxFS в HP-UX: 0
- HFS на HP-UX: 0
- HFS в Mac OS X: 0
Я еще не исследовал сетевые файловые системы.
Вопрос: Как я могу элегантно объяснить другим, что их сценарии неверны ?
На мой взгляд, «правильной» версией будет:
if test ! -s ./log/cr_trig.log
then
echo "Badness: Log not empty"
exit 25
fi
filesystems
shell-script
ls
compatibility
MattBianco
источник
источник
Ответы:
Очень интересная находка. Хотя я никогда не
ls -s
проверял, является ли файл пустым или нет, я бы предположил, что он также сообщает0
о пустых файлах.На ваш вопрос: Как уже прокомментировал Мат , покажите им свои результаты теста. Чтобы объяснить им результаты, укажите, что в
ls -s
отчете указано количество выделенных блоков в файловой системе, а не фактический размер в байтах. Очевидно, что некоторые реализации файловой системы выделяют блоки, даже если им не нужно хранить какие-либо данные, вместо того, чтобы хранить только нулевой указатель в inode.Объяснение этому может быть связано с производительностью. Создание пустых файлов, которые останутся пустыми, является исключением для обычной обработки (наиболее распространенное использование, которое я видел, было бы созданием файлов состояния, где наличие файла представляет определенное состояние программного обеспечения).
Но обычно созданный файл скоро получит некоторые данные, поэтому разработчики определенной ФС, возможно, предполагали, что стоит сразу выделить блок данных при создании файла, поэтому, когда поступают первые данные, эта задача уже выполнена.
Вторая причина может заключаться в том, что файл в прошлом содержал данные, которые были стерты. Вместо освобождения последнего блока данных может оказаться целесообразным сохранить этот блок данных для повторного использования в том же файле.
РЕДАКТИРОВАТЬ:
На ум пришла еще одна причина: файловыми системами, в которых вы нашли значения> 0, являются ZFS , реализация RAID + LVM + FS и GFS , кластерная файловая система. Оба могут хранить метаданные для сохранения целостности файлов, которые не хранятся в inode. Это может быть то, что
ls -s
считается в блоках данных, выделенных для этих метаданных.источник
В отличие от большинства (если не всех) других файловых систем, ZFS не выделяет статический массив inode заранее. При создании пустого файла в ZFS будет использоваться новый блок данных, о котором сообщает
ls -s
.Я подозреваю, что GFS должен хранить данные синхронизации / блокировки, приводящие к другому ненулевому результату.
источник
ls -s
сообщает о количестве блоков, выделенных для файла, не считая того, что хранится непосредственно в записи каталога.В большинстве случаев количество блоков - это количество байтов, деленное на размер блока в байтах, округленное в большую сторону.
Количество блоков может быть меньше, чем для разреженного файла . Например, в большинстве файловых систем это создаст 8192-байтовый файл, охватывающий 0 блоков:
И наоборот, количество блоков может быть больше, если файловая система предварительно выделяет блоки для файлов или использует блоки для хранения метаданных. Я не удивлен, что Zfs имеет неочевидное соответствие между размером файла и количеством блоков, учитывая большое количество функций, которые он предлагает, и его ориентацию на большие файловые системы; Я не знаю деталей, но количество блоков зависит не только от размера файлов, но и от его истории (вы можете иметь более одного блока в пустом файле, если это результат усечения файла большего размера).
Чтобы объяснить, почему
ls -s
это неправильно: он не учитывает размер файла, а зависит от файловой системы. Это очень косвенный способ определить, является ли файл пустым, во-первых, требующий внешнего инструмента (ls
) и некоторого анализа; вместо этого они должны использоватьtest -s
, что не требует анализа и выполняет именно то, что запрашивается. Если они считают, чтоls -s
это хороший способ проверить, является ли файл пустым, ответственность за него должна быть возложена на него.источник