Я только что «mv» отредактировал каталог 49GB на неверный путь к файлу, возможно ли восстановить исходное состояние файлов?

58

У меня есть (ну, у меня был ) каталог:

/media/admin/my_data

Он был размером около 49 ГБ и содержал десятки тысяч файлов. Каталог является точкой монтирования активного раздела LUKS.

Я хотел переименовать каталог в:

/media/admin/my_data_on_60GB_partition

В то время я не понимал, но я выполнил команду из домашнего каталога, поэтому я сделал:

~% sudo mv /media/admin/my_data my_data_on_60GB_partition

Итак, mvпрограмма начала перемещаться /media/admin/my_dataи ее содержимое в новый каталог ~/my_data_on_60GB_partition.

Я использовал Ctrl+, Cчтобы отменить команду, так что теперь у меня есть целая куча файлов, разбитых по каталогам:

~/my_data_on_60GB_partition    <---  about 2GB worth files in here

а также

/media/admin/my_data           <---- about 47GB of orig files in here    

Новый каталог ~/my_data_on_60GB_partitionи некоторые его подкаталоги принадлежат пользователю root.
Я предполагаю, что mvпрограмма сначала скопировала файлы как root, а затем после передачи chownвернула их обратно в мою учетную запись.

У меня есть несколько старых резервных копий каталога / раздела.
У меня вопрос, можно ли надежно восстановить кучу файлов, которые были перемещены?

То есть я могу просто запустить:

sudo mv ~/my_data_on_60GB_partition/*  /media/admin/my_data

или я должен отказаться от попыток восстановления, поскольку файлы, возможно, повреждены и частично завершены и т. д.?

  • ОС - Ubuntu 16.04
mv --version  
mv (GNU coreutils) 8.25
the_velour_fog
источник
36
Привыкайте при панике набирать Control-Z(паузу), а не Control-C. В этом случае вы сможете увидеть, какой файл был передан в то время, и узнать, какой файл был скопирован только частично. Затем вы можете спокойно решить, как поступить. (Использовать kill -stopдля процессов не в tty).
meuh
1
2 ГБ + 47 ГБ = 60 ГБ ???
tbodt
7
@tbodt (2GB + 47GB) < 60GB. Емкость раздела составляет 60 ГБ, размер папки и ее содержимое: 49 ГБ.
the_velour_fog

Ответы:

87

При перемещении файлов между файловыми системами mvне удаляет файл до завершения его копирования и обрабатывает файлы последовательно (я изначально говорил, что копирует, а затем удаляет каждый файл по очереди, но это не гарантировано - по крайней мере, mvкопии GNU затем удаляют каждую команду). аргумент строки в свою очередь, и POSIX определяет это поведение ). Таким образом, в целевом каталоге должен быть не более одного неполного файла, а оригинал все равно будет находиться в исходном каталоге.

Чтобы переместить вещи назад, добавьте -iфлаг, чтобы mvничего не перезаписывать:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

(при условии, что у вас нет скрытых файлов для восстановления ~/my_data_on_60GB_partition/) или, что еще лучше (учитывая, что, как вы обнаружили, у вас может быть много файлов, ожидающих удаления), добавьте -nфлаг, чтобы mvничего не перезаписывать, но не спросить вас об этом:

sudo mv -n ~/my_data_on_60GB_partition/* /media/admin/my_data/

Вы также можете добавить -vфлаг, чтобы увидеть, что делается.

С любым POSIX-совместимым mvисходная структура каталогов все еще должна быть неповрежденной, так что в качестве альтернативы вы можете проверить это - и просто удалить /media/admin/my_data... (Хотя в общем случае, я думаю, что mv -nвариант является безопасным подходом - он обрабатывает все формы mv, в том числе, например mv /media/admin/my_data/* my_data_on_60GB_partition/ .)

Вам, вероятно, потребуется восстановить некоторые разрешения; Вы можете сделать это массово, используя chownи chmod, или восстановить их из резервных копий, используя getfaclи setfacl(спасибо Сато Кацура за напоминание ).

Стивен Китт
источник
Спасибо Стивену Китту, это огромная помощь! Я могу использовать, findчтобы найти и установить разрешения. В новом каталоге есть много файлов, в именах которых есть пробелы, но нет скрытых файлов - о которых я знаю. Как вы думаете, глобус в команде sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/расширит имя файла без проблем с разделением слов? Я думал альтернативно, я мог бы использовать, sudo rsync ~/my_data_on_60GB_partition/ /media/admin/my_data/который я считаю, будет обрабатывать пути к файлам с пробелами?
the_velour_fog
6
Просто чтобы быть уверенным, что когда описываются такие вещи, как описанный OP, я использую rsyncвместо этого, чтобы он также проверял целостность всех файлов. Но приятно знать, что мне это не нужно.
Хаулет
1
@the_velour_fog globbing обрабатывает пробелы в именах файлов без проблем.
Стивен Китт
5
Я бы su command mv -i ...(или su /bin/mv -i ...) вместо sudo mv -i ...) на случай, если какой-нибудь (странный) админ сделает mv функцией, которая выполняет mv -f на системном уровне (т. Е. / Etc / profile или такие общесистемные файлы) .. команда что-то: запустить команду что-то, а не функцию или псевдоним с тем же именем. (например: можно (очень!) не повезти и иметь (очень, очень плохо!) function mv { /bin/mv -f -- "$@" }в файле, который всегда получен, и тогда «rm -i что-то» ничего не спросит (и просто возразит, что «-i "файла не существует!) ... [Я видел такие вещи ... дрожь ]
Оливье Дюлак
3
@OlivierDulac - прекрасный пример того, почему плохая практика - использовать псевдонимы или сценарии с такими же именами, что и у стандартных программ.
Джо
19

После получения ответа Стивена Китта и обсуждения этой команды как потенциального решения:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Я решил отложить его, пока не пойму, что происходит, этот ответ описывает то, что я узнал и в итоге сделал.

Я использую Gnu, mvкоторая копирует файлы в целевой каталог, тогда, только если операция копирования прошла успешно, она удаляет оригинал.
Однако я хотел проверить, mvвыполняет ли эта последовательность по одному файлу за раз, если это правда, исходное содержимое папки было бы аккуратно разделено на две части, одна часть сместилась к месту назначения, а другая все еще осталась в источнике. И, возможно, во время копирования будет один файл, который будет прерван между двумя каталогами, и он, вероятно, будет поврежден.

Чтобы обнаружить файлы, которые были общими для двух каталогов, я запустил:

~% sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

Этот результат показал, что в исходных и целевых каталогах было 14 237 экземпляров одинаковых файлов, я подтвердил, проверив файлы вручную - да, в обоих каталогах было много одинаковых файлов. Это говорит о том, что только после mvкопирования больших наборов файлов выполняется удаление исходных файлов. Быстрый поиск в infoпо mvкоманде показал

mvСначала он [ ] использует тот же код, который использовался cp -aдля копирования запрошенных каталогов и файлов, а затем (при условии успешного завершения копирования) удаляет оригиналы. Если копирование не удалось, то часть, которая была скопирована в целевой раздел, удаляется.

Я не запускал команду, но подозреваю, что попытался запустить

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

-i Подсказка перед перезаписью вероятно бы вызвало более чем 14.000 раз.

Итак, чтобы узнать, сколько всего файлов во вновь созданном каталоге:

~% sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

Итак, если в новом каталоге было в общей сложности 14238 обычных файлов и 14237 имели идентичные оригиналы обратно в источнике, это означает, что в новом каталоге был только один файл, который не имел соответствующего идентичного файла в исходном каталоге. Чтобы узнать, что это был за файл, я запустил rsync в направлении источника:

~% sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

Быстрая проверка подтвердила, что это был неправильно сформированный файл, где файл существовал как в источнике, так и в месте назначения, файл назначения = 64 МБ, оригинал = 100 МБ. Этот файл и его иерархия каталогов все еще принадлежали пользователю root, и исходные разрешения для него еще не восстановлены.

Итак, в заключение:

  • все файлы, которые mvникогда не были найдены, все еще вернулись на свои места (очевидно)
  • все файлы, которые mvкопировались полностью, все еще имели свои оригинальные копии в исходном каталоге
  • файл, который был скопирован только частично, по-прежнему имел оригинал в исходном каталоге

Другими словами, все исходные файлы все еще не были повреждены, и в этом случае решением было просто удалить новый каталог!

the_velour_fog
источник
Ух ты ... я обновил свой ответ, -nбыло бы лучше в общем случае. Я проверил mvисходный код, он удаляет исходный аргумент за раз.
Стивен Китт
@StephenKitt ах хорошо. Мне было интересно, когда mvпроисходит удаление на источнике. Таким образом, команда mv foo bar bazбудет двигаться fooв baz/foo том удалить оригинал fooзатем перейти barк baz/bar..?
the_velour_fog
Да это правильно; фактически это то, что определяет POSIX (в основном, так что любая ошибка, затрагивающая любой аргумент источника, оставляет всю иерархию источника нетронутой).
Стивен Китт
Я думаю, что вы могли бы использовать diff, чтобы найти и один незаконченный файл.
StarWeaver
1
Вы должны использовать, cmpа не diffсравнивать двоичные файлы. Кроме того, ваше обсуждение выше имеет смысл только при перемещении файлов между различными файловыми системами. При перемещении файлов в одной и той же файловой системе не происходит копирования.
Satō Katsura
4

Я просто подумал, что прокомментирую, что у некоторых людей может возникнуть желание бросить «xargs» в микс для параллельной работы. Это дает мне волю, и мне действительно нравится решение rsync выше.

Что касается файловой системы о перемещении и копировании, а также о том, когда именно оригинал удаляется, VFS и базовая файловая система (системы) координируют действия, чтобы гарантировать атомарность для каждого файла перед переходом к этому этапу удаления. Таким образом, даже если он прерывается до полной записи целевого файла, вся блокировка в VFS очень строгая и защищает от таких вещей, как случайное чередование данных, даже в параллельных случаях. (Я работал над Linux VFS и NFS4)

Добавление 'xargs' к смеси, вероятно, сделало бы этап проверки двойного здравомыслия головной болью, когда несколько файлов находились в середине пути. Хотелось бы, чтобы у меня было больше сценариев на уровне системы. Хорошие напоминания для меня!

Мне понравился вопрос, он хорош для паутины и заставляет меня снова любить rsync. Ура!

Дэвид Рихтер
источник
1
Не говоря уже о проблеме, когда имена файлов содержат пробелы.
Подстановочный