Como @samiam ha declarado, la lista se le devuelve en un orden semialeatorio a través de readdir()
. Solo agregaré lo siguiente.
La lista devuelta es lo que llamaría el orden del directorio. En sistemas de archivos más antiguos, el orden suele ser el orden de creación en el que se agregaron las entradas de archivo en la tabla del directorio. Por supuesto, existe una advertencia al respecto, cuando se elimina una entrada de directorio, esta entrada se recicla, por lo que cualquier archivo posterior que se almacene reemplazará a la entrada anterior, por lo que el pedido ya no se basará únicamente en el tiempo de creación.
En los sistemas de archivos modernos donde las estructuras de datos de directorio se basan en un árbol de búsqueda o una tabla hash, el orden es prácticamente impredecible.
Ejemplos
Al hurgar en los archivos creados cuando ejecuta su comando táctil, se revelan los siguientes inodes asignados.
$ touch dir/{{1..8},{a..p}}
$ stat --printf="%n -- %i\n" dir/*
dir/1 -- 10883235
dir/2 -- 10883236
dir/3 -- 10883242
dir/4 -- 10883243
dir/5 -- 10883244
dir/6 -- 10883245
dir/7 -- 10883246
dir/8 -- 10883247
dir/a -- 10883248
dir/b -- 10883249
dir/c -- 10883250
dir/d -- 10883251
dir/e -- 10883252
dir/f -- 10883253
dir/g -- 10883254
dir/h -- 10883255
dir/i -- 10883256
dir/j -- 10883299
dir/k -- 10883302
dir/l -- 10883303
dir/m -- 10883311
dir/n -- 10883424
dir/o -- 10883426
dir/p -- 10883427
Por lo tanto, podemos ver que la expansión de llaves utilizada por el tacto crea los nombres de los archivos en orden alfabético y, por lo tanto, se les asignan números de inodo secuenciales cuando se escriben en el HDD. (Sin embargo, eso no influye en el orden en el directorio).
Ejecutar su tar
comando varias veces parece indicar que hay un orden en la lista, ya que ejecutarlo varias veces produce la misma lista cada vez. Aquí lo ejecuté 100 veces y luego comparé las ejecuciones y todas son idénticas.
$ for i in {1..100};do tar cJvf file.tar.xz dir/ > run${i};done
$ for i in {1..100};do cmp run1 run${i};done
$
Si eliminamos estratégicamente say dir/e
y luego agregamos un nuevo archivo dir/ee
, podemos ver que este nuevo archivo ha ocupado el lugar que dir/e
ocupaba anteriormente en la tabla de entradas de directorios.
$ rm dir/e
$ touch dir/ee
Ahora mantengamos la salida de uno de los for
bucles anteriores, solo el primero.
$ mv run1 r1A
Ahora, si volvemos a ejecutar el for
ciclo que ejecutará el tar
comando 100 veces nuevamente, y compararemos esta segunda ejecución con la anterior:
$ sdiff r1A run1
dir/ dir/
...
dir/c dir/c
dir/f dir/f
dir/e | dir/ee
dir/o dir/o
dir/2 dir/2
...
Notamos que dir/ee
ha ocupado dir/e
su lugar en la tabla de directorios.
stat --printf='%i\t-- %n\n' * | sort -n | sed 's/.*\t-- //'
ls -f
orls -U
orfind -maxdepth 1
-f
bandera proviene del antiguo Unix. Su propósito era ser rápido. Inhabilitó la clasificación, la omisión de archivos de puntos y algunas otras cosas. El-U
indicador es una innovación de GNU que le permite deshabilitar la clasificación sin ningún otro efecto secundario.readdir()
básicamente. Cuando tar descubre qué archivos hay en un directorio, solicita directamente al núcleo una lista de archivos a través deopendir()
seguido dereaddir()
.readdir()
no devuelve los archivos en ningún orden en particular; la forma en que se ordenan los archivos depende del sistema de archivos utilizado por el kernel de Linux.Ahí, desafortunadamente, no hay una opción para
tar
ordenar archivos en subdirectorios (agregar uno se deja como un ejercicio para el lector).fuente
f_op->iterate
llamada que glibcreaddir()
finalmente filtra a través degetdents()
se asigna a una implementación específica del sistema de archivos. No puedo ver nada en un nivel superior que reordene losdirent
retornos de la implementación de fs.