Como @samiam declarou que a lista é retornada para você em um pedido semi-aleatório via readdir()
. Vou apenas adicionar o seguinte.
A lista retornada é o que eu chamaria de ordem de diretório. Em sistemas de arquivos mais antigos, a ordem geralmente é a ordem de criação na qual as entradas do arquivo na tabela do diretório foram adicionadas. É claro que há uma ressalva, quando uma entrada de diretório é excluída, essa entrada é reciclada, portanto, qualquer arquivo subseqüente armazenado substituirá a entrada anterior, portanto, o pedido não será mais baseado apenas no tempo de criação.
Em sistemas de arquivos modernos, onde as estruturas de dados de diretório são baseadas em uma árvore de busca ou tabela de hash, a ordem é praticamente imprevisível.
Exemplos
Cutucar os arquivos criados quando você executa o comando touch revela que os inodes a seguir foram atribuídos.
$ 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
Assim, podemos ver que a expansão de chave usada pelo touch cria os nomes dos arquivos em ordem alfabética e, portanto, eles recebem números de inode seqüenciais quando gravados no HDD. (Isso, no entanto, não influencia a ordem no diretório.)
Executar o comando tar
várias vezes parece indicar que há uma ordem na lista, já que executá-lo várias vezes gera a mesma lista a cada vez. Aqui eu corri 100 vezes e então comparei as corridas e todas são 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
$
Se excluirmos estrategicamente o dir/e
e, em seguida, adicionarmos um novo arquivo dir/ee
, poderemos ver que esse novo arquivo ocupou o lugar que dir/e
ocupou antes na tabela de entradas de diretórios.
$ rm dir/e
$ touch dir/ee
Agora vamos manter a saída de um dos loop for
acima, apenas o 1º.
$ mv run1 r1A
Agora, se executarmos novamente o loop for
que executará o comando tar
100 vezes novamente e compararemos essa segunda execução com a 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
...
Percebemos que dir/ee
ocupou o lugar de dir/e
na tabela de diretórios.