Por que o mv é muito mais rápido que o cp? Como me recupero de um comando mv incorreto?

17

Arrasto e solto uma pasta em outra por engano no FileZilla.

~/big_folder
~/some_other_folder

A pasta foi movida é muito grande. Inclui centenas de milhares de arquivos (node_modules, pequenos arquivos de imagem, muitas pastas)

O que é tão estranho é que, depois que solto o mouse, a mudança está concluída. A pasta "big_folder" é movida para "some_other_folder".

~/some_other_folder/big_folder

(não há big_folderno ~/depois de se mudar)

Então percebo o erro e tento voltar, mas ele falha no FileZilla e no terminal.

Tenho que cp -rcopiar os arquivos novamente, porque existem códigos do servidor acessando esses arquivos em~/big_folder

E demora uma eternidade para esperar ...

O que devo fazer?

BTW, aqui estão os resultados do FileZilla (é a falha do retorno):

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
fonte
37
Ah, a mais útil das mensagens de erro received failure with description 'Failure',.
Captain Man
3
Ir para um terminal e digite o comando mv /root/some_other_folder/big_folder /root/big_folder. Que mensagem de erro você recebe?
ctrl-alt-delor
Provavelmente eu iria comcp -al
Nemo
1
A mv vs cppergunta do OP é abordada, mas eu gostaria de saber por que ele conseguiu mover a pasta em uma direção instantaneamente, mas não na outra.
user1717828
4
Pelo mesmo motivo, é muito mais rápido mover um livro de uma sala para outra do que criar uma cópia do livro.
David Richerby

Respostas:

63

Se um diretório for movido dentro do mesmo sistema de arquivos (a mesma partição), tudo o que é necessário é renomear o caminho do arquivo do diretório. Nenhum dado além da entrada do diretório em si deve ser alterado.

Ao copiar diretórios, os dados de cada arquivo precisam ser duplicados. Isso envolve a leitura de todos os dados de origem e a gravação no destino.

Mover um diretório entre sistemas de arquivos envolveria copiar os dados para o destino e removê-los da fonte. Isso levaria tanto tempo quanto copiar (duplicar) os dados em um único sistema de arquivos.


Se o FileZilla renomeou com sucesso o diretório de ~/big_folderpara ~/some_other_folder/big_folder, então eu reverteria isso usando

mv ~/some_other_folder/big_folder ~/big_folder

... após a primeira certificando-se de que não havia diretório chamado ~/big_folder(se houvesse, a medida vai colocar big_folderpartir some_other_folderpara o ~/big_folderdiretório como uma subpasta).

Kusalananda
fonte
6
Ah ... é por isso que vejo a palavra "renomear" em vez de "mover" na saída?
AGamePlayer
2
@AGamePlayer Sim, correto.
Kusalananda
4
@AGamePlayer "Falha" infelizmente não é uma boa descrição de erro. Eu teria usado mv ~/some_other_folder/big_folder ~/depois de me certificar de que não há outro big_folderno diretório inicial. Eu nunca usei o FileZilla.
Kusalananda
10
Outro motivo para não depender das ferramentas da GUI do Windows para fazer alguma manutenção de arquivo no Unix.
9788 Mark Stewart
4
@ MarkStewart por que "no Unix" no final do seu comentário ?; Existe um momento em que é uma boa ideia?
ctrl-alt-delor
11

A resposta existente é ótima, mas eu gostaria de expandir um pouco, mostrando exatamente o que está acontecendo quando você se move ou quando copia um arquivo. Quando você olha para os syscalls durante uma cópia, vê:

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

Isso abre o arquivo de origem e cria um segundo arquivo. Em seguida, ele lê o conteúdo do arquivo de origem na memória e grava essa memória no arquivo de destino. Isso requer várias opções de contexto e algumas E / S de disco que podem ser bastante altas para arquivos grandes. Se você mover um arquivo, no entanto, verá:

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

É importante lembrar que você só verá o arquivo renomeado se estiver na mesma partição no mesmo disco físico. Se você criar um arquivo enorme de vários gigabytes e depois o mover entre dois locais em sua casa, notará que a ação é concluída instantaneamente. Se, por outro lado, você o mover para um dispositivo externo, levará tanto tempo para mover como se você o tivesse usado cp. Isso ocorre porque a movimentação de um arquivo só pode ser feita renomeando-o se estiver na mesma partição.

floresta
fonte
O OP moveu um diretório, não um arquivo.
AL
Ele ainda se aplicam tho, a menos que OP está se movendo pastas vazias, o que seria o único caso em que há arquivos estão envolvidos
glace
@AL Nos sistemas Unix, tudo é um arquivo.
Thegs
@AL Um arquivo de texto foi apenas um exemplo. Para um diretório, a única diferença é que você teria algum getdents()e mkdir()chamadas espalhada ao redor.
forest