Perché mv è molto più veloce di cp? Come posso recuperare da un comando mv errato?


17

Trascino una cartella in un'altra per errore in FileZilla.

~/big_folder
~/some_other_folder

La cartella spostata è molto grande. Include centinaia di migliaia di file (node_modules, piccoli file di immagine, molte cartelle)

Ciò che è così strano è che dopo aver rilasciato il mouse, lo spostamento è fatto. La cartella "big_folder" viene spostata in "some_other_folder".

~/some_other_folder/big_folder

(non c'è big_foldernel ~/dopo lo spostamento)

Poi mi rendo conto dell'errore e provo a tornare indietro ma non riesce sia su FileZilla che sul terminale.

Quindi devo cp -rcopiare nuovamente i file perché ci sono codici sul lato server che accedono a quei file~/big_folder

E ci vuole un'eternità ad aspettare ...

Cosa dovrei fare?

A proposito, ecco l'output di FileZilla (è il fallimento del tornare indietro):

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'

37
Ah, il più utile dei messaggi di errore, received failure with description 'Failure'.
Captain Man,

3
Vai a un terminale e digita il comando mv /root/some_other_folder/big_folder /root/big_folder. Che messaggio di errore ricevi?
ctrl-alt-delor,

Probabilmente ci andreicp -al
Nemo il

1
La mv vs cpdomanda di OP è indirizzata, ma mi piacerebbe sapere perché è stato in grado di spostare istantaneamente la cartella in una direzione ma non nell'altra.
user1717828

4
Per lo stesso motivo, è molto più veloce spostare un libro da una stanza all'altra che creare una copia del libro.
David Richerby,

Risposte:


63

Se una directory viene spostata all'interno dello stesso filesystem (la stessa partizione), è sufficiente rinominare il percorso del file della directory. Nessun dato diverso dalla voce della directory per la directory stessa deve essere modificato.

Quando si copiano le directory, i dati per ogni singolo file devono essere duplicati. Ciò comporta la lettura di tutti i dati di origine e la loro scrittura nella destinazione.

Spostare una directory tra i filesystem comporterebbe la copia dei dati nella destinazione e la loro rimozione dall'origine. Ciò richiederebbe tanto tempo quanto la copia (duplicazione) dei dati all'interno di un singolo filesystem.


Se FileZilla rinominasse con successo la directory da ~/big_foldera ~/some_other_folder/big_folder, allora lo ripristinerei usando

mv ~/some_other_folder/big_folder ~/big_folder

... dopo la prima assicurandosi che non c'erano directory chiamata ~/big_folder(se non ci fosse, lo spostamento avrebbe messo big_folderda some_other_foldernella ~/big_folderdirectory come sottocartella).


6
Oh ... è per questo che vedo la parola "rinominare" piuttosto che "spostare" nell'output?
AGamePlayer

2
@AGamePlayer Sì, corretto.
Kusalananda

4
@AGamePlayer "Failure" non è purtroppo una buona descrizione dell'errore. Avrei usato mv ~/some_other_folder/big_folder ~/dopo essermi assicurato che non ci fosse altro big_foldernella home directory. Non ho mai usato FileZilla.
Kusalananda

10
Un altro motivo per non dipendere dagli strumenti della GUI di Windows per eseguire un po 'di manutenzione dei file su Unix.
Mark Stewart,

4
@MarkStewart perché "su Unix" alla fine del tuo commento ?; C'è un momento in cui è una buona idea?
ctrl-alt-delor,

11

La risposta esistente è ottima, ma vorrei espanderla un po 'mostrando esattamente cosa sta succedendo quando ci si sposta rispetto a quando si copia un file. Quando guardi i syscalls durante una copia, vedi:

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

Questo apre il file sorgente, quindi crea un secondo file. Quindi legge il contenuto del file sorgente in memoria e scrive quella memoria nel file di destinazione. Ciò richiede diversi switch di contesto e alcuni I / O del disco che possono essere piuttosto elevati per file di grandi dimensioni. Tuttavia, se sposti un file, vedi:

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

È importante ricordare che il file verrà rinominato solo se si trova sulla stessa partizione sullo stesso disco fisico. Se crei un enorme file multi-gigabyte e poi lo sposti tra due posizioni nella tua casa, noterai che l'azione si completa immediatamente. Se invece lo sposti su un dispositivo esterno, ci vorrà tanto tempo per spostarti come se lo avessi usato cpinvece. Questo perché lo spostamento di un file può essere fatto rinominandolo solo se si trova sulla stessa partizione.


L'OP ha spostato una directory, non un file.
AL

Si applica comunque, a meno che OP non stia spostando le cartelle vuote, il che sarebbe l'unico caso in cui non sono coinvolti file
glace

@AL Nei sistemi simili a Unix tutto è un file.
Thegs

@AL Un file di testo era solo un esempio. Per una directory, l'unica differenza è che avresti avuto alcune getdents()e mkdir()chiamate sparse in giro.
foresta,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.