¿Cuándo `ls -s` imprime“ 0 ”

13

Por supuesto, la forma estándar de probar si un archivo está vacío es con test -s FILE, pero uno de nuestros clientes ha recibido un script que contiene pruebas como esta:

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 las afirmaciones del proveedor de que funciona en los dos entornos en los que lo han probado. No hace falta decir que falló gravemente en los dos lugares donde lo probé.

Entonces, me dio curiosidad. ¿Cuándo se ls -simprime 0para archivos vacíos?

Estos son mis hallazgos hasta ahora:

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

Todavía no he examinado los sistemas de archivos en red.

Pregunta: ¿Cómo puedo explicar elegantemente a los demás que sus guiones están equivocados ?

En mi opinión, la versión "correcta" sería:

if test ! -s ./log/cr_trig.log
then
    echo "Badness: Log not empty"
    exit 25
fi
MattBianco
fuente
55
Solo muéstrales tus pruebas. Tiene datos sólidos que prueban que su prueba no es portátil, ¿qué más necesita?
Mat
Una de las preguntas más interesantes que he visto hasta ahora en este servidor. Lástima que uno solo pueda gastar un punto.
ktf 01 de
@ktf Siempre puedes otorgar una recompensa.
Joe

Respuestas:

6

Muy interesante hallazgo. Aunque nunca he usado ls -spara verificar si un archivo está vacío o no, habría asumido que también informa 0de archivos vacíos.

A su pregunta: Como Mat ya comentó, muéstreles los resultados de su prueba. Para explicarles los resultados, indique que ls -sinforma la cantidad de bloques asignados en el sistema de archivos, no el tamaño real en bytes. Obviamente, algunas implementaciones de sistemas de archivos asignan bloques incluso si no tienen que almacenar ningún dato en lugar de almacenar solo un puntero NULL en el inodo.

La explicación de esto puede estar relacionada con el rendimiento. Crear archivos vacíos que permanecerán vacíos es una excepción para el procesamiento normal (el uso más común que he visto sería la creación de archivos de estado donde la existencia de un archivo representa un cierto estado del software).

Pero normalmente, un archivo creado obtendrá algunos datos pronto, por lo que los diseñadores de un determinado FS pueden haber asumido que vale la pena asignar inmediatamente un bloque de datos al crear el archivo, de modo que cuando lleguen los primeros datos, esta tarea ya está hecha.

La segunda razón podría ser que un archivo contenía datos que se borraron en el pasado. En lugar de liberar el último bloque de datos, puede valer la pena mantener ese bloque de datos para que el mismo archivo lo reutilice.

EDITAR:

Se me ocurrió una razón más: los sistemas de archivos en los que ha encontrado valores> 0 son ZFS , la implementación RAID + LVM + FS y GFS , un sistema de archivos en clúster. Es posible que ambos tengan que almacenar metadatos para mantener la integridad del archivo que no se almacena en inodes. Puede ser que ls -scuente en bloques de datos asignados para estos metadatos.

ktf
fuente
4

A diferencia de la mayoría (si no todos) otros sistemas de archivos, ZFS no asigna previamente una matriz estática de inodos. Al crear un archivo vacío en ZFS, se usará un nuevo bloque de datos que es el que informa ls -s.

Sospecho que GFS tiene que almacenar datos de sincronización / bloqueo que conducen al otro resultado distinto de cero.

jlliagre
fuente
2

ls -s informa el número de bloques asignados para el archivo, sin incluir lo que esté almacenado directamente en la entrada del directorio.

En la mayoría de los casos, el número de bloques es el número de bytes dividido por el tamaño del bloque en bytes, redondeado hacia arriba.

El número de bloques puede ser menor que el de un archivo disperso . Por ejemplo, en la mayoría de los sistemas de archivos, esto creará un archivo de 8192 bytes que abarca 0 bloques:

$ 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

Por el contrario, el número de bloques puede ser mayor si el sistema de archivos asigna previamente bloques para archivos o usa bloques para almacenar metadatos. No me sorprende que Zfs tenga una correspondencia no obvia entre el tamaño del archivo y el número de bloques, dada la gran cantidad de características que ofrece y su orientación hacia grandes sistemas de archivos; No conozco los detalles, pero la cantidad de bloques depende no solo del tamaño de los archivos sino también de su historial (puede tener más de un bloque en un archivo vacío si es el resultado de truncar un archivo más grande).

Para explicar por qué ls -sestá mal: no cuenta el tamaño del archivo, sino una cantidad dependiente del sistema de archivos. Es una forma muy indirecta de determinar si un archivo está vacío en primer lugar, lo que requiere una herramienta externa ( ls) y algún análisis; en su lugar, deberían usar test -s, lo que no requiere análisis y realiza exactamente lo que se solicita. Si piensan que ls -ses una buena manera de probar si un archivo está vacío, debe recaer sobre ellos para justificar que funciona.

Gilles 'SO- deja de ser malvado'
fuente