O que acontece se o mv for interrompido?

72

O que acontece se o mvcomando Linux for interrompido? Digamos, estou movendo um diretório inteiro para outro lugar e o interrompo enquanto ele estiver em movimento. O diretório de origem continuará intocado?

dehmann
fonte

Respostas:

51

Se você mover um diretório no mesmo sistema de arquivos, somente moverá a entrada do diretório de um local no sistema de arquivos para outro. Por exemplo, mv /source/dir /target/dirirá apagar a entrada de diretório de dirpartir /sourcee criar um novo em /target. Isso é feito por uma chamada do sistema atômico (ou seja, ininterrupta). O inode que contém as entradas do diretório dire o conteúdo real do próprio diretório não é afetado.

Se você mover o diretório de um sistema de arquivos para outro, todos os arquivos serão copiados primeiro para o novo sistema de arquivos e depois desvinculados do original. Portanto, se você interromper mva cópia, poderá acabar com duas cópias de alguns dos arquivos - no local antigo e no novo.

bmk
fonte
6
@Wesley: Não, não haverá arquivo parcial. Se o sistema permanecer ativo (por exemplo, você pressionar ctrl-C), ele será removido automaticamente. Caso contrário (por exemplo, perda de energia), o arquivo parcial pode ser deixado em algum lugar inacessível no disco de destino, mas deve ser limpo no próximo fsck(que provavelmente será executado automaticamente na reinicialização, pois o disco não foi desmontado corretamente).
Dave Sherohman
50
Errado. Se você mover dir de um fs para outro mv / fs1 / dir / fs2 / e você interromper, / fs1 / dir / ficará aqui completamente. / fs1 / dir é removido somente quando a movimentação estiver concluída.
8
user263131 está certo. Executar strace mv /fs1/dir /fs2/- a última coisa que o mv faz é chamar unlinkattodos os arquivos de origem de uma só vez (não um por um, pois são copiados).
Jakob
7
@JJ Parece que é porque você usou uma expansão do bash; nesse caso, o mv trata cada arquivo da expansão como uma fonte separada (fazendo-os individualmente).
precisa saber é o seguinte
5
Então .... @bmk ou outros, você deseja atualizar esta resposta para ser menos ... errado?
Artem Russakovskii
35

A implementação GNU repete os argumentos na linha de comando, tenta renomear primeiro e, se isso falhar, copia recursivamente e exclui recursivamente a fonte. assim

mv a b c/

excluirá a antes de copiar b e não começará a excluir nada em a antes que a cópia de destino seja concluída.

Observe que isso se aplica apenas à implementação GNU.

Para esclarecer: se um é um diretório que contém d e e , e b é um arquivo, a ordem será

  • criar c / a
  • copiar a / d -> c / a / d
  • copiar a / e -> c / a / e
  • excluir a / d
  • excluir a / e
  • excluir um
  • cópia b -> c / b
  • excluir b
Simon Richter
fonte
11
Você pode fornecer uma fonte para isso? Outros respondentes estão dizendo que um arquivo de origem é excluído imediatamente após ser copiado para um fs diferente (ou seja, nem todos são copiados e todos são excluídos).
jamesbtate
11
Experiência. Adicionei um exemplo para deixar mais claro como minha resposta e as outras são consistentes. Se você listar apenas arquivos individuais, na verdade cada arquivo será excluído imediatamente.
Simon Richter
Observo o comportamento descrito nesta resposta no macOS, ou seja, com um BSD mvtambém, portanto, não é apenas GNU.
kirelagin
12

Você move um diretório, interrompe a movimentação e o diretório original permanece intacto:

$ mv a b/

Se você mover vários diretórios, cada um ficará intacto na origem ou no destino, dependendo de quando você interrompeu:

$ mv a b c/

Como recebi minha resposta:

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

Como teste, copiei uma pasta grande para um diretório NFS, interrompi e o número de arquivos na pasta grande de origem permaneceu o mesmo, e o conteúdo parcial foi deixado no diretório NFS. Eu usei "find. -Type f | wc -l" para verificar.

Parece que a resposta de Simon está correta.

user79878
fonte
9

A resposta aceita está definitivamente errada sobre a mudança entre sistemas de arquivos - um fato que já me salvou muitos problemas algumas vezes. Ao mover um diretório que contém subdiretórios, nenhum arquivo em um subdiretório será excluído antes que todo o subdiretório tenha sido copiado. Ou seja, entre o significado real de "objeto por objeto" - um subdiretório É um objeto (arquivo) e, portanto, sua integridade deve ser preservada por uma cópia completa no destino antes que qualquer coisa possa ser excluída. Portanto, a resposta de Simon me parece a correta.

bhak
fonte
4

Não. O mv opera objeto por objeto; portanto, os objetos que já foram processados ​​serão removidos da fonte.

Ignacio Vazquez-Abrams
fonte
2

Definitivamente não. A movimentação é feita objeto a objeto. Portanto, o objeto movido para o destino até o ponto de interrupção não deve mais existir na fonte.

Se o mv foi emitido para um arquivo grande (entre diferentes) e foi interrompido, a fonte estará intacta. No alvo, você verá um arquivo incompleto até o ponto de interrupção.

No entanto, você pode restaurar o mv com o mesmo comando e o processo continuará.

g24l
fonte
2

Se você deseja interromper o mv porque deseja desconectar-se do terminal, basta enviá-lo para segundo plano:

* press Ctrl+Z

# bg
# disown
Курочка Ряба
fonte
11
Esse é um bom ponto, mas não responde à pergunta real.
Julie Pelletier
11
@JuliePelletier, mas é isso que eu estava procurando, para que alguém possa estar interessado em fazer isso.
Курочка Ряба