Co się stanie, jeśli mv zostanie przerwane?

72

Co się stanie, jeśli mvpolecenie Linuksa zostanie przerwane? Powiedzmy, że przenoszę cały katalog w inne miejsce i przerywam go podczas przenoszenia. Czy katalog źródłowy nadal pozostanie nietknięty?

dehmann
źródło

Odpowiedzi:

51

Jeśli przenosisz katalog w tym samym systemie plików, możesz przenieść pozycję katalogu tylko z jednej lokalizacji w systemie plików do innej. Np. mv /source/dir /target/dirUsunie pozycję katalogu dirz /sourcei utworzy nową w /target. Odbywa się to za pomocą jednego wywołania systemu atomowego (tj. Nieprzerwanego). Nie dirma to wpływu na i- węzeł zawierający wpisy katalogu, a także faktyczną zawartość samego katalogu.

Jeśli katalog zostanie przeniesiony z jednego systemu plików do innego, wszystkie pliki zostaną najpierw skopiowane do nowego systemu plików, a następnie odłączone od oryginalnego. Jeśli więc przerwiesz mvpodczas kopiowania, możesz skończyć z dwiema kopiami niektórych plików - w starej lokalizacji i w nowej.

bmk
źródło
6
@Wesley: Nie, nie będzie częściowego pliku. Jeśli system pozostanie włączony (np. Naciśniesz Ctrl-C), zostanie on automatycznie usunięty. Jeśli nie (np. Utrata zasilania), plik częściowy może zostać pozostawiony w miejscu niedostępnym na dysku docelowym, ale powinien zostać wyczyszczony do następnego fsck(który najprawdopodobniej uruchomi się automatycznie przy ponownym uruchomieniu, ponieważ dysk nie został odmontowany w sposób czysty).
Dave Sherohman,
50
Źle. Jeśli przeniesiesz katalog z jednego fs do drugiego mv / fs1 / dir / fs2 / i przerwiesz, / fs1 / dir / pozostanie tutaj całkowicie. / fs1 / dir jest usuwany tylko po zakończeniu przenoszenia.
8
użytkownik 263131 ma rację. Uruchom strace mv /fs1/dir /fs2/- ostatnią rzeczą, którą robi mv, jest wywoływanie unlinkatwszystkich plików źródłowych jednocześnie (nie jeden po drugim, gdy są kopiowane).
Jakob
7
@JJ Wygląda na to, że użyłeś rozszerzenia bash, w którym to przypadku mv traktuje każdy plik w rozwinięciu jako osobne źródło (robiąc je indywidualnie).
gkanwar
5
Więc ... @bmk lub inni, czy chcesz zaktualizować tę odpowiedź, aby była mniej ... błędna?
Artem Russakovskii
35

Implementacja GNU iteruje argumenty w wierszu poleceń, najpierw próbuje zmienić nazwę, a jeśli to się nie powiedzie, rekurencyjnie kopiuje, a następnie rekurencyjnie usuwa źródło. Więc

mv a b c/

usunie przed skopiowaniem b , i nie rozpocznie usuwania czegokolwiek w przed kopiowaniem docelowy jest kompletna.

Zauważ, że dotyczy to tylko implementacji GNU.

Aby wyjaśnić: jeśli jest katalogiem zawierającym d i e , i b jest plikiem, kolejność będzie

  • utwórz c / a
  • skopiuj a / d -> c / a / d
  • skopiuj a / e -> c / a / e
  • usuń a / d
  • usuń a / e
  • usuń a
  • skopiuj b -> c / b
  • usuń b
Simon Richter
źródło
1
Czy możesz podać źródło tego? Inni autorzy twierdzą, że plik źródłowy jest usuwany natychmiast po skopiowaniu do innego pliku (tzn. Nie wszystkie są kopiowane, a następnie usuwane).
jamesbtate
1
Doświadczenie. Dodałem przykład, aby wyjaśnić, w jaki sposób moja odpowiedź i pozostałe są spójne. Jeśli wymienisz tylko pojedyncze pliki, to rzeczywiście każdy plik zostanie natychmiast usunięty.
Simon Richter
Obserwuję zachowanie opisane w tej odpowiedzi na macOS, to znaczy również z BSD mv, więc nie jest to tylko GNU.
kirelagin
12

Przenosisz jeden katalog, przerywasz przenoszenie, a oryginalny katalog pozostanie nienaruszony:

$ mv a b/

Jeśli przeniesiesz wiele katalogów, każdy z nich pozostanie nienaruszony na źródle lub miejscu docelowym, w zależności od tego, kiedy przerwałeś:

$ mv a b c/

Jak otrzymałem odpowiedź:

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

W ramach testu skopiowałem duży folder do katalogu NFS, przerwałem, a liczba plików w dużym źródłowym folderze pozostała taka sama, a częściowa zawartość pozostała w katalogu NFS. Użyłem „find. -Type f | wc -l” do weryfikacji.

Wygląda na to, że odpowiedź Simona jest poprawna.

użytkownik79878
źródło
9

Przyjęta odpowiedź jest zdecydowanie błędna w kwestii przechodzenia między systemami plików - fakt, który już kilka razy zaoszczędził mi wielu kłopotów. Podczas przenoszenia katalogu zawierającego podkatalogi żaden plik w podkatalogu nie zostanie usunięty przed skopiowaniem całego podkatalogu. To znaczy, btw. Rzeczywiste znaczenie „obiekt po obiekcie” - podkatalog JEST obiektem (plikiem), a zatem jego integralność musi zostać zachowana przez pełną kopię w miejscu docelowym, zanim cokolwiek zostanie usunięte. Tak więc odpowiedź Simona wydaje mi się poprawna.

bhak
źródło
4

Nie. Mv obsługuje obiekt po obiekcie, więc obiekty, które zostały już przetworzone, zostaną usunięte ze źródła.

Ignacio Vazquez-Abrams
źródło
2

Zdecydowanie nie. Ruch jest wykonywany obiekt po obiekcie. Dlatego obiekt przeniesiony do miejsca docelowego do momentu przerwania nie będzie już istniał w źródle.

Jeśli mv zostało wydane dla dużego pliku (między różnymi) i zostało przerwane, źródło pozostanie nienaruszone. Na celu zobaczysz niekompletny plik do momentu przerwania.

Możesz jednak przywrócić mv za pomocą tego samego polecenia, a proces będzie kontynuowany.

g24l
źródło
2

Jeśli chcesz przerwać mv, ponieważ chcesz rozłączyć się z terminalem, możesz po prostu wysłać go do tła:

* press Ctrl+Z

# bg
# disown
Курочка Ряба
źródło
1
To dobra uwaga, ale nie odpowiada na rzeczywiste pytanie.
Julie Pelletier
1
@JuliePelletier, ale tego właśnie szukałem, aby ktoś mógł być tym zainteresowany.
Курочка Ряба