Quando `ls -s` stampa“ 0 ”


13

Naturalmente, il modo standard di testare se un file è vuoto è con test -s FILE, ma uno dei nostri clienti ha ricevuto uno script contenente test come questo:

RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
    echo "Badness: Log not empty"
    exit 25
fi

con affermazioni da parte del fornitore che funziona nei due ambienti in cui lo hanno testato. Inutile dire che è fallito gravemente in entrambi i due punti in cui l'ho testato.

Quindi, mi sono incuriosito. Quando ls -sstampa 0file vuoti?

Questa è la mia scoperta finora:

  • GFS su Linux: 4
  • ext4 su Linux: 0
  • ZFS su Solaris: 1
  • UFS su Solaris: 0
  • jfs su AIX: 0
  • VxFS su HP-UX: 0
  • HFS su HP-UX: 0
  • HFS su Mac OS X: 0

Non ho ancora esaminato i file system in rete.

Domanda: Come posso spiegare elegantemente agli altri che i loro script sono sbagliati ?

Secondo me, la versione "corretta" sarebbe:

if test ! -s ./log/cr_trig.log
then
    echo "Badness: Log not empty"
    exit 25
fi

5
Mostra loro i tuoi test. Hai dati concreti che dimostrano che il loro test non è portatile, cos'altro ti serve?
Mat

Una delle domande più interessanti che ho visto finora su questo server. Peccato che uno possa spendere solo un punto.
ktf,

@ktf Puoi sempre assegnare una taglia.
Joe,

Risposte:


6

Scoperta molto interessante. Anche se non ho mai usato ls -sper verificare se un file è vuoto o meno, avrei ipotizzato che riferisse anche 0per file vuoti.

Alla tua domanda: come Mat ha già commentato, mostra loro i risultati del test. Per spiegare loro i risultati, indica che ls -sriporta la quantità di blocchi allocati nel filesystem, non la dimensione effettiva in byte. Ovviamente alcune implementazioni del filesystem allocano i blocchi anche se non devono archiviare alcun dato invece di memorizzare solo un puntatore NULL nell'inode.

La spiegazione di ciò può essere correlata alle prestazioni. Creare file vuoti che rimarranno vuoti è un'eccezione per l'elaborazione normale (l'uso più comune che ho visto sarebbe la creazione di file di stato in cui l'esistenza di un file rappresenta un certo stato del software).

Ma normalmente un file creato otterrà presto alcuni dati, quindi i progettisti di un certo FS possono aver supposto che ripagare immediatamente l'assegnazione di un blocco di dati alla creazione del file, quindi quando arrivano i primi dati questa attività è già stata eseguita.

Il secondo motivo potrebbe essere che in passato un file conteneva dati che sono stati cancellati. Invece di liberare l'ultimo blocco di dati potrebbe essere utile conservare quel blocco di dati per riutilizzarlo dallo stesso file.

MODIFICARE:

Un altro motivo è venuto in mente: i filesystem in cui sono stati trovati valori> 0 sono ZFS , l'implementazione RAID + LVM + FS e GFS , un filesystem cluster. Entrambi potrebbero dover archiviare metadati per mantenere l'integrità dei file che non è archiviata negli inode. Potrebbe essere che ls -sconta nei blocchi di dati allocati per questi metadati.


4

A differenza della maggior parte degli altri file system (se non di tutti), ZFS non prealloca un array statico di inode. La creazione di un file vuoto su ZFS utilizzerà quindi un nuovo blocco di dati che è quello segnalato da ls -s.

Sospetto che GFS debba archiviare i dati di sincronizzazione / blocco che portano all'altro risultato diverso da zero.


2

ls -s riporta il numero di blocchi allocati per il file, escluso tutto ciò che è memorizzato direttamente nella voce della directory.

Nella maggior parte dei casi, il numero di blocchi è il numero di byte diviso per la dimensione del blocco in byte, arrotondato per eccesso.

Il numero di blocchi può essere inferiore a quello per un file sparse . Ad esempio, sulla maggior parte dei filesystem, questo creerà un file a 8192 byte che si estende su 0 blocchi:

$ 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

Al contrario, il numero di blocchi può essere maggiore se il filesystem prealloca i blocchi per i file o usa i blocchi per memorizzare i metadati. Non mi sorprende che Zfs abbia una corrispondenza non ovvia tra dimensione del file e numero di blocchi, dato il gran numero di funzionalità che offre e il suo orientamento verso file system di grandi dimensioni; Non conosco i dettagli, ma il numero di blocchi dipende non solo dalla dimensione dei file ma anche dalla sua cronologia (puoi avere più di un blocco in un file vuoto se è il risultato del troncamento di un file più grande).

Spiegare perché ls -sè sbagliato: non conta la dimensione del file, ma una quantità dipendente dal filesystem. È un modo molto indiretto per determinare se un file è vuoto in primo luogo, che richiede uno strumento esterno ( ls) e qualche analisi; invece, dovrebbero usare test -s, che non richiede analisi, ed eseguire esattamente ciò che è richiesto. Se pensano che ls -ssia un buon modo per testare se un file è vuoto, l'onere dovrebbe essere su di loro per giustificare che funzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.