Коли `ls -s` друкує" 0 "


13

Звичайно, стандартний спосіб тестування, якщо файл порожній, є 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 на Solaris: 1
  • UFS на Solaris: 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

5
Просто покажіть їм свої тести. У вас є важкі дані, які підтверджують, що їх тест не є портативним, що ще потрібно?
Мат

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

@ktf Ви завжди можете нагородити.
Джо

Відповіді:


6

Дуже цікава знахідка. Хоча я ніколи не ls -sперевіряв, чи файл порожній чи ні, я би припустив, що він також звітує 0про порожні файли.

На ваше запитання: Як Мат вже коментував, покажіть їм свої результати тесту. Щоб пояснити їм результати, констатуйте, що ls -sповідомляє кількість виділених блоків у файловій системі, а не фактичний розмір у байтах. Очевидно, деякі реалізації файлової системи виділяють блоки, навіть якщо їм не потрібно зберігати будь-які дані, а не зберігати лише вказівник NULL в inode.

Пояснення цього може бути пов'язане з роботою. Створення порожніх файлів, які залишатимуться порожніми, - це вихід для звичайної обробки (найпоширенішим використанням, яке я бачив, було б створення файлів статусу, де існування файлу являє собою певний стан програмного забезпечення).

Але зазвичай створений файл незабаром отримає деякі дані, тому дизайнери певної ФС можуть припустити, що він окупається негайно виділити блок даних при створенні файлу, тому коли перші дані надійдуть, це завдання вже виконано.

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

Редагувати:

Ще одна причина прийшла до тями: файлові системи, де ви знайшли значення> 0, - це ZFS , реалізація RAID + LVM + FS та GFS , файлова система кластера. Обом, можливо, доведеться зберігати метадані, щоб підтримувати цілісність файлів, які не зберігаються у inodes. Можливо, ls -sпідраховується в блоках даних, виділених для цих метаданих.


4

На відміну від більшості (якщо не всіх) інших файлових систем, ZFS не виділяє статичний масив узорів. Створення порожнього файлу на ZFS використовує новий блок даних, про який повідомляє ls -s.

Я підозрюю, що GFS повинен зберігати дані синхронізації / блокування, що ведуть до іншого ненульового результату.


2

ls -s повідомляє про кількість блоків, виділених для файлу, не враховуючи того, що зберігається безпосередньо у записі каталогу.

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

Кількість блоків може бути меншою, ніж для розрідженого файлу . Наприклад, у більшості файлових систем це створить 8192-байтовий файл, що охоплює 0 блоків:

$ perl -e 'truncate STDOUT, 8192' >a
$ ls -l a
-rw-r--r-- 1 gilles gilles 8192 Nov  1 21:32 a
$ ls -s a
0 a

І навпаки, кількість блоків може бути більшою, якщо файлова система попередньо розміщує блоки для файлів або використовує блоки для зберігання метаданих. Я не здивований, що Zfs має очевидну відповідність між розміром файлу та кількістю блоків, враховуючи велику кількість функцій, які він пропонує, та його орієнтацію на великі файлові системи; Я не знаю деталей, але кількість блоків залежить не тільки від розміру файлів, але і від його історії (у порожньому файлі ви можете мати більше одного блоку, якщо це результат обрізання більшого файлу).

Щоб пояснити, чому ls -sце неправильно: він враховує не розмір файлу, а кількість, залежну від файлової системи. Це дуже непрямий спосіб визначити, чи файл у першу чергу порожній, що вимагає зовнішнього інструменту ( ls) та деякого розбору; натомість вони повинні використовувати test -s, що не вимагає розбору, і виконувати саме те, що потрібно. Якщо вони вважають, що ls -sце хороший спосіб перевірити, чи файл порожній, на них слід наголосити, щоб виправдати, що він працює.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.