Что произойдет, если mv прервется?

72

Что произойдет, если команда Linux mvбудет прервана? Скажем, я перемещаю весь каталог в другое место и прерываю его, пока он движется. Будет ли исходный каталог еще не тронут?

dehmann
источник

Ответы:

51

Если вы перемещаете каталог в той же файловой системе, вы перемещаете запись каталога только из одного места в файловой системе в другое. Например, mv /source/dir /target/dirудалит запись каталога из dirfrom /sourceи создаст новую в /target. Это делается одним атомным системным вызовом (то есть непрерывным). Индекс, содержащий записи каталога, dirа также фактическое содержимое самого каталога, не затрагивается.

Если вы перемещаете каталог из одной файловой системы в другую, все файлы сначала копируются в новую файловую систему, а затем отсоединяются от исходной. Поэтому, если вы прервете mvво время копирования, вы можете получить две копии некоторых файлов - в старом месте и в новом.

БМК
источник
6
@ Уэсли: Нет, частичного файла не будет. Если система продолжает работать (например, вы нажали Ctrl-C), она будет удалена автоматически. Если нет (например, потеря питания), частичный файл может быть оставлен где-то недоступным на целевом диске, но должен быть очищен следующим fsck(который, скорее всего, будет запускаться автоматически при перезагрузке, поскольку диск не был размонтирован без ошибок).
Дейв Шерохман
50
Неправильно. Если вы переместите dir с одного fs на другой mv / fs1 / dir / fs2 / и прервитесь, / fs1 / dir / останется здесь полностью. / fs1 / dir удаляется только после завершения перемещения.
8
Пользователь263131 прав. Выполнить strace mv /fs1/dir /fs2/- самое последнее, что делает mv - это вызов unlinkatвсех исходных файлов одновременно (не один за другим, когда они копируются).
Якоб
7
@JJ Похоже, это потому, что вы использовали расширение bash, и в этом случае mv рассматривает каждый файл в расширении как отдельный источник (таким образом, делая их по отдельности).
gkanwar
5
Итак .... @bmk или другие, вы хотите обновить этот ответ, чтобы быть менее ... неправильным?
Артем Руссаковский
35

Реализация GNU перебирает аргументы в командной строке, сначала пытается переименовать, а в случае неудачи рекурсивно копирует, а затем рекурсивно удаляет источник. Так

mv a b c/

удалит a перед копированием b и не начнет удалять что-либо в a до завершения целевой копии.

Обратите внимание, что это относится только к реализации GNU.

Чтобы уточнить: если a является каталогом, содержащим d и e , а b является файлом, порядок будет

  • создать с / а
  • копировать а / д -> с / а / д
  • скопировать / e -> c / a / e
  • удалить а / д
  • удалить а / е
  • удалить
  • копия b -> c / b
  • удалить б
Саймон Рихтер
источник
1
Можете ли вы предоставить источник для этого? Другие отвечающие говорят, что исходный файл удаляется сразу после того, как он скопирован на другой файл (то есть не все скопированы, а все удалены).
jamesbtate
1
Опыт. Я добавил пример, чтобы прояснить, насколько мой ответ и другие согласованы. Если вы перечисляете только отдельные файлы, то каждый файл будет удален немедленно.
Саймон Рихтер
Я наблюдаю поведение, описанное в этом ответе, на macOS, то есть с BSD mv, поэтому оно не только для GNU.
Кирелагин
12

Вы перемещаете один каталог, прерываете перемещение, и исходный каталог остается неизменным:

$ mv a b/

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

$ mv a b c/

Как я получил свой ответ:

$ mv --version
mv (GNU coreutils) 8.21

$ info mv
... It first uses some of the same code that's used by `cp -a'
to copy the requested directories and files, then (assuming the copy
succeeded) it removes the originals.  If the copy fails, then the part
that was copied to the destination partition is removed.  If you were
to copy three directories from one partition to another and the copy of
the first directory succeeded, but the second didn't, the first would
be left on the destination partition and the second and third would be
left on the original partition.

В качестве теста я скопировал большую папку в каталог NFS, прервался, и количество файлов в моей большой исходной папке осталось прежним, а частичное содержимое осталось в каталоге NFS. Я использовал "find. -Type f | wc -l" для проверки.

Похоже, что ответ Саймона правильный.

user79878
источник
9

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

бхак
источник
4

Нет. Mv управляет объект за объектом, поэтому объекты, которые уже были обработаны, будут удалены из источника.

Игнасио Васкес-Абрамс
источник
2

Определенно нет. Движение производится объект за объектом. Следовательно, объект, перемещенный к месту назначения до точки прерывания, больше не должен существовать в источнике.

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

Однако вы можете восстановить mv с помощью той же команды, и процесс продолжится.

g24l
источник
2

Если вы хотите прервать mv, потому что хотите отключиться от терминала, вы можете просто отправить его в фоновый режим:

* press Ctrl+Z

# bg
# disown
Курочка Ряба
источник
1
Это хороший момент, но он не отвечает на настоящий вопрос.
Джули Пеллетье
1
@JuliePelletier, но это то, что я искал, так что кто-то может быть заинтересован в этом.
Курочка Ряба