Що станеться, якщо mv перервано?


72

Що станеться, якщо команда Linux mvперервана? Скажімо, я переміщую цілий каталог в якесь інше місце і перериваю його, поки він рухається. Чи буде вихідний каталог все-таки недоторканим?

Відповіді:


51

Якщо ви переміщаєте каталог в одній і тій же файловій системі, ви переміщуєте запис каталогу лише з одного місця файлової системи в інше. Наприклад, mv /source/dir /target/dirвидалить запис каталогу dirз /sourceі створить новий в /target. Це робиться одним викликом атомної системи (тобто безперебійним). Вплив, що містить записи каталогів dir, а також власне вміст самого каталогу не впливає.

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


6
@Wesley: Ні, часткового файлу не буде. Якщо система не працює (наприклад, ви натиснете 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 - файл, буде порядок

  • створити c / a
  • скопіюйте a / d -> c / a / d
  • скопіюйте a / e -> c / a / e
  • видалити а / д
  • видалити a / e
  • видалити a
  • копія b -> c / b
  • видалити b

1
Чи можете ви надати джерело для цього? Інші відповідачі кажуть, що вихідний файл видаляється одразу після його копіювання в інший FS (тобто не всі скопійовані, а потім усі видалені).
jamesbtate

1
Досвід. Я додав приклад, щоб зрозуміти, наскільки моя відповідь та інші відповідають. Якщо ви перераховуєте лише окремі файли, то дійсно кожен файл буде видалений негайно.
Саймон Ріхтер

Я спостерігаю за поведінкою, описаною в цій відповіді на macOS, тобто з BSD mv, тому це не лише GNU.
kirelagin

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. -Тип f | wc -l".

Схоже, відповідь Саймона правильна.


9

Прийнята відповідь, безумовно, помилкова в переході між файловими системами - факт, який врятував мені багато клопотів уже пару разів. При переміщенні каталогу, який містить підкаталоги, жоден файл у підкаталозі не буде видалений до того, як буде скопійовано весь підкаталог. Це, однак, власне значення "об'єкт за об'єктом" - підкаталог IS є об'єктом (файлом), і, таким чином, його цілісність повинна бути збережена повною копією в пункті призначення, перш ніж щось можна буде видалити. Тож відповідь Саймона видається мені правильною.



2

Однозначно ні. Переміщення робиться об'єктом за об'єктом. Отже, об’єкт, переміщений до пункту призначення аж до точки переривання, вже не буде існувати у джерелі.

Якщо mv був виданий для великого файлу (між різними) і він був перерваний, джерело буде недоторканим. На цілі ви побачите неповний файл до моменту переривання.

Однак ви можете відновити mv за допомогою тієї ж команди, і процес триватиме.


2

Якщо ви хочете перервати mv через відключення від терміналу, можете просто надіслати його на другий план:

* press Ctrl+Z

# bg
# disown

1
Це хороший момент, але він не відповідає на власне питання.
Джулі Пелтьє

1
@JuliePelletier, але це те, що я шукав, щоб хтось був зацікавлений у цьому.
Курочка Ряба
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.