Есть ли какой-то порядок операций rm
? Я выполнил операцию rm
в большом каталоге и мне интересно, где мне посмотреть, что могло быть удалено. rm
Работает ли сначала с файлами, а затем с каталогами? Или это основано на какой-то информации в таблице инодов?
Характеристики: rm из GNU coreutils 8.22 Система: Arch Linux, работающая на файловой системе beagleboneblack, работающей на внешнем жестком диске Seagate (ext4) с использованием USB 2.0.
Предыстория:
Я выполнял очистку каталога и выполнил
cp -r A/ B/ C/ Dest/
Невольно я продолжил:
rm -r A/ B/ C/ Dest/
когда я имел в виду просто выступить
rm -r A/ B/ C/
Я поймал это и нажал Ctrl+ C, прежде чем прошло слишком много времени. В частности, это было < 3 секунд, так как я использовал команду time
в сочетании с rm
& cp
. Я вошел и проверил, Dest/
ожидая, что его не будет, но, о чудо, он был целым ипоявилсяне быть затронутыми. Это немного удивительно, так как A/
B/
C/
они довольно малы. Может быть, 100–200 МБ в общей сложности. Dest/
однако, это чуть меньше 1 ТБ. Выполнение ls
на Dest/ показало, что были и файлы, и каталоги на обоих концах алфавита (например AFile.txt
.... .... Zoo.txt
).
Мне повезло, и я отменил rm
до того, как он нанес ущерб моему каталогу Dest/? rm
Неужели так медленно (к счастью!)?
Если нет, то как rm
рекурсивно удалить данные, чтобы я мог предположить, что именно было потеряно?
Я на самом деле не рассчитываю вернуть то, что я мог потерять, просто интересно, что именно могло быть утеряно.
решение1
rm -r
работает с каждым из своих аргументов по очереди. Если аргумент является каталогом, он перечисляет каталог (сopendir
иreaddir
функции или какой-либо эквивалентный метод) и работает с каждой записью по очереди. Если запись является каталогом, он исследует эту запись рекурсивно.
Это точно такой же метод, который используют другие приложения для рекурсивного обхода каталогов — find
, ls -Rf
, и т. д.
Порядок обхода непредсказуем. В большинстве файловых систем порядок воспроизводим, пока в каталоге не добавляются, не удаляются и не переименовываются файлы (теоретически порядок может быть совершенно случайным и меняться каждый раз, но я не могу вспомнить файловую систему, где это происходит). В некоторых файловых системах порядок в целом можно вывести из имен файлов или из порядка, в котором файлы были созданы, или из комбинации того и другого, но вам нужно знать тонкие детали файловой системы, и он может меняться в зависимости от версии драйвера. Порядок обхода — это не то, на что можно положиться.
Обратите внимание, что ls
или echo *
сортируйте файлы в лексикографическом порядке их имен. find
или ls -f
не сортируйте.
Единственное, на что можно положиться, это то, что аргументы обрабатываются по порядку. Так что если бы C/
он все еще был частично там, это означало бы, что Dest/
он нетронут. Если C/
он исчез, вы можете получить представление о том, где были удалены файлы, Dest/
проверив время изменения каталога и сравнив его со временем C/
удаления или временем окончания копирования. Первым файлом, который будет удален, может быть файл, находящийся непосредственно в Dest/
иерархии или где-то глубоко в ней, в зависимости от того, была ли первая запись, Dest/
которая rm
прошла через каталог, или нет.
Скорость rm
в основном зависит от того, сколько файлов нужно удалить. Чтобы заметно повлиять на время удаления, нужен очень большой файл. Основная часть работы — это удаление каждой записи каталога по очереди. Данные файла не стираются, для стирания содержимого файла требуется только пометить блоки, которые он использовал, как свободные, что относительно быстро.
решение2
Как говорит Жиль, в общем случае невозможно предсказать порядок удалений в каталоге, можно лишь предположить, что каталоги верхнего уровня будут обработаны в порядке, указанном в командной строке.
Однако вам также гарантировано, что он удалит иерархии каталогов снизу вверх, поскольку Unix позволяет удалять каталоги только в том случае, если они пусты. Поэтому, чтобы удалить каталог, сначала нужно удалить все в нем. Если он содержит подкаталоги, сначала нужно удалить их содержимое и так далее.