Come ha affermato @samiam, l'elenco viene restituito in un ordine semi-casuale tramite readdir()
. Aggiungerò solo quanto segue.
L'elenco restituito è ciò che definirei l'ordine delle directory. Sui file system meno recenti, l'ordine è spesso l'ordine di creazione in cui sono state aggiunte le voci del file nella tabella della directory. Ovviamente c'è un avvertimento a questo, quando una voce della directory viene eliminata, questa voce viene quindi riciclata, quindi tutti i file successivi che vengono memorizzati sostituiranno la voce precedente, quindi l'ordine non sarà più basato esclusivamente sul tempo di creazione.
Sui moderni filesystem in cui le strutture di dati di directory sono basate su un albero di ricerca o una tabella hash, l'ordine è praticamente imprevedibile.
Esempi
Frugando sui file creati quando si esegue il comando touch, vengono rivelati i seguenti inode.
$ 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
Quindi possiamo vedere che l'espansione del controvento usata dal tocco crea i nomi dei file in ordine alfabetico e quindi sono assegnati numeri di inode sequenziali quando sono scritti sull'HDD. (Ciò tuttavia non influenza l'ordine nella directory.)
L'esecuzione del tar
comando più volte sembra indicare che esiste un ordine nell'elenco, poiché l'esecuzione più volte produce lo stesso elenco ogni volta. Qui l'ho eseguito 100 volte e poi ho confrontato le piste e sono tutte identiche.
$ 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
$
Se eliminiamo strategicamente say dir/e
e quindi aggiungiamo un nuovo file dir/ee
, possiamo vedere che questo nuovo file ha preso il posto che dir/e
occupava prima nella tabella delle voci delle directory.
$ rm dir/e
$ touch dir/ee
Ora manteniamo l'output di uno dei for
loop sopra, solo il primo.
$ mv run1 r1A
Ora, se eseguiamo nuovamente il for
ciclo che eseguirà tar
nuovamente il comando 100 volte e confronteremo questa seconda esecuzione con la precedente:
$ 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
...
Notiamo che dir/ee
ha preso dir/e
posto nella tabella delle directory.
stat --printf='%i\t-- %n\n' * | sort -n | sed 's/.*\t-- //'