Dlaczego mv jest o wiele szybszy niż CP? Jak odzyskać po nieprawidłowym poleceniu mv?

17

Przeciągam i upuszczam folder przez pomyłkę w FileZilla.

~/big_folder
~/some_other_folder

Przeniesiony folder jest bardzo ogromny. Zawiera setki tysięcy plików (moduły_węzła, małe pliki obrazów, dużo folderów)

Dziwne jest to, że po zwolnieniu myszy ruch jest zakończony. Folder „big_folder” zostaje przeniesiony do „some_other_folder”.

~/some_other_folder/big_folder

(nie ma big_folderw ~/po przeprowadzce)

Potem zdaję sobie sprawę z błędu i spróbuj cofnąć się, ale nie powiedzie się to zarówno w FileZilla, jak i terminalu.

Następnie muszę cp -rskopiować pliki z powrotem, ponieważ istnieją kody po stronie serwera uzyskujące dostęp do tych plików~/big_folder

I trzeba czekać wiecznie ...

Co powinienem zrobić?

BTW, oto dane wyjściowe z FileZilla (jest to błąd cofania się):

Status:       Renaming '/root/big_folder' to '/root/some_other_folder/big_folder'
Status:       /root/big_folder -> /root/some_other_folder/big_folder

Status:       Renaming '/root/some_other_folder/big_folder' to '/root/big_folder'
Command:  mv "big_folder" "/root/big_folder"
Error:          mv /root/some_other_folder/big_folder /root/big_folder: received failure with description 'Failure'
AGamePlayer
źródło
37
Ach, najbardziej użyteczne komunikatów o błędach received failure with description 'Failure'.
Captain Man,
3
Przejdź do terminala i wpisz polecenie mv /root/some_other_folder/big_folder /root/big_folder. Jaki komunikat o błędzie pojawia się?
ctrl-alt-delor
Prawdopodobnie bym poszedł zcp -al
Nemo,
1
mv vs cpPytanie OP jest adresowane, ale chciałbym usłyszeć, dlaczego był w stanie przesunąć folder natychmiast w jednym kierunku, ale nie w drugim.
user1717828,
4
Z tego samego powodu, że przenoszenie książki z jednego pokoju do drugiego jest znacznie szybsze niż tworzenie kopii książki.
David Richerby,

Odpowiedzi:

63

Jeśli katalog zostanie przeniesiony w tym samym systemie plików (tej samej partycji), wystarczy zmienić nazwę ścieżki do katalogu. Żadne dane oprócz pozycji katalogu dla samego katalogu nie muszą być zmieniane.

Podczas kopiowania katalogów dane dla każdego pliku muszą zostać zduplikowane. Obejmuje to odczytanie wszystkich danych źródłowych i zapisanie ich w miejscu docelowym.

Przeniesienie katalogu między systemami plików wymagałoby skopiowania danych do miejsca docelowego i usunięcia ich ze źródła. Zajmie to tyle samo czasu, co kopiowanie (duplikowanie) danych w jednym systemie plików.


Jeśli FileZilla z powodzeniem zmienił nazwę katalogu z ~/big_folderna ~/some_other_folder/big_folder, to przywróciłbym to za pomocą

mv ~/some_other_folder/big_folder ~/big_folder

... po pierwszym upewniając się, że nie ma katalogu o nazwie ~/big_folder(jeśli nie było, że ruch będzie umieścić big_folderod some_other_folderdo ~/big_folderkatalogu jako podfolder).

Kusalananda
źródło
6
Och ... czy to dlatego widzę słowo „zmiana nazwy”, a nie „ruch” na wyjściu?
AGamePlayer,
2
@AGamePlayer Tak, poprawne.
Kusalananda
4
@AGamePlayer „Błąd” niestety nie jest dobrym opisem błędu. Użyłbym mv ~/some_other_folder/big_folder ~/po upewnieniu się, że nie ma innych big_folderw katalogu domowym. Nigdy nie korzystałem z FileZilla.
Kusalananda
10
Kolejny powód, dla którego nie należy polegać na narzędziach GUI systemu Windows w celu konserwacji plików w systemie Unix.
Mark Stewart
4
@ MarkStewart, dlaczego „na Unixie” na końcu komentarza ?; Czy jest czas, kiedy jest to dobry pomysł?
ctrl-alt-delor
11

Istniejąca odpowiedź jest świetna, ale chciałbym ją nieco rozwinąć, pokazując dokładnie, co dzieje się podczas przenoszenia, a nie podczas kopiowania pliku. Kiedy patrzysz na syscalls podczas kopiowania, widzisz:

open("hello1.txt", O_RDONLY)               = 3
open("hello2.txt", O_WRONLY|O_CREAT, 0644) = 4
read(3, "Hello, world!\n", 4096)           = 14
write(4, "Hello, world!\n", 14)            = 14
close(3)                                   = 0
close(4)                                   = 0

Spowoduje to otwarcie pliku źródłowego, a następnie utworzenie drugiego pliku. Następnie odczytuje zawartość pliku źródłowego do pamięci i zapisuje tę pamięć do pliku docelowego. Wymaga to kilku przełączników kontekstu i niektórych dyskowych operacji we / wy, które mogą być dość wysokie w przypadku dużych plików. Jeśli jednak przeniesiesz plik, zobaczysz:

rename("hello1.txt", "hello2.txt")         = 0

Należy pamiętać, że nazwa pliku będzie widoczna tylko wtedy, gdy znajduje się na tej samej partycji na tym samym dysku fizycznym. Jeśli utworzysz ogromny, wielobajtowy plik, a następnie przeniesiesz go między dwie lokalizacje w domu, zauważysz, że akcja zakończy się natychmiast. Jeśli natomiast przeniesiesz je na urządzenie zewnętrzne, przeniesienie zajmie tyle samo czasu, jak w przypadku użycia cp. Wynika to z faktu, że przeniesienie pliku można wykonać tylko poprzez zmianę jego nazwy, jeśli znajduje się on na tej samej partycji.

las
źródło
OP przeniósł katalog, a nie plik.
AL
To nadal obowiązuje, chyba że OP przenosi puste foldery, co byłoby jedynym przypadkiem, w którym nie są zaangażowane żadne pliki
glace
@AL W systemach uniksowych wszystko jest plikiem.
Thegs,
@AL Plik tekstowy był tylko przykładem. W przypadku katalogu jedyną różnicą jest to, że będziesz mieć trochę getdents()i mkdir()połączeń rozsypanych wokół.
las