Bien sûr, la façon standard de tester si un fichier est vide est avec test -s FILE
, mais l'un de nos clients a reçu un script contenant des tests comme celui-ci:
RETVAL=`ls -s ./log/cr_trig.log | awk '{print $1}'`
if test $RETVAL -ne 0
then
echo "Badness: Log not empty"
exit 25
fi
avec les affirmations du fournisseur selon lesquelles il fonctionne dans les deux environnements dans lesquels ils l'ont testé. Inutile de dire qu'il a mal échoué aux deux endroits où je l'ai testé.
Alors, je suis devenu curieux. Quand ls -s
imprime-t-on 0
pour les fichiers vides?
Voici mes conclusions jusqu'à présent:
- GFS sur Linux: 4
- ext4 sous Linux: 0
- ZFS sur Solaris: 1
- UFS sur Solaris: 0
- jfs sur AIX: 0
- VxFS sur HP-UX: 0
- HFS sur HP-UX: 0
- HFS sur Mac OS X: 0
Je n'ai pas encore examiné les systèmes de fichiers en réseau.
Question: Comment puis-je expliquer avec élégance aux autres que leurs scripts sont faux ?
À mon avis, la version "correcte" serait:
if test ! -s ./log/cr_trig.log
then
echo "Badness: Log not empty"
exit 25
fi
filesystems
shell-script
ls
compatibility
MattBianco
la source
la source
Réponses:
Constatation très intéressante. Bien que je n'ai jamais utilisé
ls -s
pour vérifier si un fichier est vide ou non, j'aurais supposé qu'il signale également0
les fichiers vides.À votre question: comme l'a déjà fait remarquer Mat , montrez-leur les résultats de votre test. Pour leur expliquer les résultats, indiquez que
ls -s
la quantité de blocs alloués dans le système de fichiers est indiquée, et non la taille réelle en octets. De toute évidence, certaines implémentations de système de fichiers allouent des blocs même si elles n'ont pas à stocker de données au lieu de stocker uniquement un pointeur NULL dans l'inode.L'explication peut être liée aux performances. Créer des fichiers vides qui resteront vides est une exception pour le traitement normal (l'usage le plus courant que j'ai vu serait la création de fichiers d'état où l'existence d'un fichier représente un certain état du logiciel).
Mais normalement, un fichier créé obtiendra bientôt des données, donc les concepteurs d'un certain FS peuvent avoir supposé qu'il est payant d'allouer immédiatement un bloc de données lors de la création du fichier, donc lorsque les premières données arrivent, cette tâche est déjà terminée.
La deuxième raison pourrait être qu'un fichier a contenu dans le passé des données qui ont été effacées. Au lieu de libérer le dernier bloc de données, il peut être utile de conserver ce bloc de données pour une réutilisation par le même fichier.
ÉDITER:
Une autre raison m'est venue à l'esprit: les systèmes de fichiers où vous avez trouvé des valeurs> 0 sont ZFS , l'implémentation RAID + LVM + FS et GFS , un système de fichiers de cluster. Les deux peuvent avoir à stocker des métadonnées pour maintenir l'intégrité des fichiers qui ne sont pas stockés dans les inodes. Il se pourrait que le
ls -s
nombre de blocs de données soit alloué à ces métadonnées.la source
Contrairement à la plupart des systèmes de fichiers (sinon tous), ZFS ne préalloue pas un tableau statique d'inodes. La création d'un fichier vide sur ZFS utilisera alors un nouveau bloc de données qui est celui signalé par
ls -s
.Je soupçonne GFS d'avoir à stocker des données de synchronisation / verrouillage menant à l'autre résultat non nul.
la source
ls -s
signale le nombre de blocs qui sont alloués au fichier, sans inclure ce qui est stocké directement dans l'entrée de répertoire.Dans la plupart des cas, le nombre de blocs est le nombre d'octets divisé par la taille du bloc en octets, arrondi.
Le nombre de blocs peut être inférieur à celui d'un fichier clairsemé . Par exemple, sur la plupart des systèmes de fichiers, cela créera un fichier de 8192 octets couvrant 0 blocs:
Inversement, le nombre de blocs peut être supérieur si le système de fichiers préalloue des blocs pour les fichiers ou utilise des blocs pour stocker des métadonnées. Je ne suis pas surpris que Zfs ait une correspondance non évidente entre la taille des fichiers et le nombre de blocs, étant donné le grand nombre de fonctionnalités qu'il offre et son orientation vers les grands systèmes de fichiers; Je ne connais pas les détails, mais le nombre de blocs dépend non seulement de la taille des fichiers mais aussi de son historique (vous pouvez avoir plus d'un bloc dans un fichier vide si c'est le résultat de tronquer un fichier plus gros).
Pour expliquer pourquoi
ls -s
est faux: il ne compte pas la taille du fichier, mais une quantité dépendante du système de fichiers. C'est une manière très indirecte de déterminer si un fichier est vide en premier lieu, nécessitant un outil externe (ls
) et une certaine analyse; au lieu de cela, ils devraient utilisertest -s
, ce qui ne nécessite aucune analyse, et effectue exactement ce qui est demandé. S'ils pensent quels -s
c'est un bon moyen de tester si un fichier est vide, c'est à eux qu'il incombe de justifier qu'il fonctionne.la source