Як визначається порядок, у якому tar працює на файлах?


15
$ touch dir/{{1..8},{a..p}}
$ tar cJvf file.tar.xz dir/
dir/
dir/o
dir/k
dir/b
dir/3
dir/1
dir/i
dir/7
dir/4
dir/e
dir/a
dir/g
dir/2
dir/d
dir/5
dir/8
dir/c
dir/n
dir/f
dir/h
dir/6
dir/l
dir/m
dir/j
dir/p

Я б очікував, що це буде в алфавітному порядку. Але, мабуть, це не так. Яка тут формула?

Відповіді:


14

Як заявив @samiam , список повертається вам у напіввипадковому порядку через readdir(). Я просто додам наступне.

Повертається список - це те, що я б назвав порядком у каталозі. У старих файлових системах часто є порядок створення, який були додані записи файлів у таблицю каталогу. Звичайно, є застереження до цього: коли запис каталогу видалено, цей запис потім рециркулюється, тому будь-які наступні файли, які зберігаються, замінять попередній запис, тому замовлення більше не ґрунтується виключно на часі створення.

У сучасних файлових системах, де структури даних каталогів базуються на дереві пошуку або хеш-таблиці, порядок є практично непередбачуваним.

Приклади

Клацання файлів, створених під час запуску сенсорної команди, виявляє наступні вставки.

$ 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

Таким чином, ми можемо бачити, що розширення дужок, яке використовується дотиком, створює назви файлів в алфавітному порядку, і тому їм присвоюється послідовний номер вводу при записі на жорсткий диск. (Однак це не впливає на порядок у каталозі.)

Виконання вашої tarкоманди кілька разів, здавалося б, вказує на те, що в списку є замовлення, оскільки його виконання кілька разів дає кожен і той самий список. Тут я запустив його 100 разів, а потім порівняв пробіжки, і всі вони однакові.

$ 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
$ 

Якщо ми стратегічно видалимо скажімо, dir/eа потім додамо новий файл, dir/eeми можемо побачити, що цей новий файл зайняв місце, яке dir/eзаймало раніше, в таблиці записів каталогів.

$ rm dir/e
$ touch dir/ee

Тепер збережемо висновок з однієї forпетлі вгорі, просто 1-ї.

$ mv run1 r1A

Тепер, якщо ми повторно запустимо forцикл, який запустить tarкоманду ще 100 разів, і порівняємо цей другий запуск з попереднім:

$ 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
...

Ми помічаємо, що dir/eeзаймає dir/eмісце в таблиці каталогів.


Ого, це справді чудова відповідь. З урахуванням каталогу, чи є для мене спосіб побачити, яким є порядок, у якому тар оброблятиме свої підпункти? Я не дуже впевнений у цьому, але як на вас виглядає наступне? stat --printf='%i\t-- %n\n' * | sort -n | sed 's/.*\t-- //'
Іван-

2
Я думаю, що це залежить від файлової системи. Я можу уявити файлову систему типу btree, яка їх сортує на основі порядку хешу файлів або чогось подібного (у мене є сенс, що старий ReiserFS замовляє їх по-іншому, оскільки ця файлова система динамічно створює
введення

1
@samiam - правильно, ця відповідь стверджує, що "порядок каталогів" - це "порядок створення, щоб записи файлів у таблицю каталогу були додані", а потім він сам показує фрагменти вмісту файлу tar, показуючи, що це неправда. Багато файлових систем, включаючи поточні файлові системи Linux * *, використовують дерева та / або хеші у структурах своїх директорій, а не прості послідовні таблиці, як деякі старі файлові системи.
Michał Politowski

3
@John ls -fабо ls -Uабоfind -maxdepth 1

1
@John -fпрапор походить від стародавнього Unix. Її метою було бути швидким. Це відключило сортування, пропуск точкових файлів та кілька інших речей. -UПрапор є нововведенням GNU , яка дозволяє відключити сортування без будь - яких інших побічних ефектів.

8

readdir()в основному. Коли tar дізнається, які файли знаходяться в каталозі, він безпосередньо запитує ядро ​​для переліку файлів, за opendir()яким слід readdir(). readdir()не повертає файли в якомусь конкретному порядку; спосіб впорядкування файлів залежить від файлової системи, яка використовується ядром Linux.

На жаль, це не варіант tarсортування файлів у підкаталогах (додавання одного залишається як вправа для читача).


1
Мені було цікаво, чи витягує їх виходячи зі значення їхнього inode?
slm

1
@slm f_op->iterateВиклик, до якого glibc readdir()врешті-решт відфільтровується через getdents(), відображається у конкретній реалізації файлової системи. Я не бачу нічого на вищому рівні, що змінює direntповернення 's fs.
Метт

@slm Ні, я ніколи не чув про файлову систему, де значення inode впливало б на порядок каталогу.
Жил 'ТАК - перестань бути злим'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.