Movimento atômico aproximado entre sistemas de arquivos?

16

Eu tenho que mover alguns arquivos de um sistema de arquivos para outro no Ubuntu. No entanto, é muito importante que os arquivos nunca existam como arquivos parciais ou incompletos no destino, pelo menos não com o nome correto.

Até agora, minha única solução é escrever um script que pegue cada arquivo, copie-o para um nome temporário no destino, renomeie-o (que acredito ser atômico) no destino para o nome do arquivo original e, finalmente, exclua o arquivo de origem .

No entanto, escrever e depurar um script parece ser um exagero para esta tarefa. Existe uma maneira ou ferramenta que já faz isso nativamente?

Niels2000
fonte
8
Sinto um problema xy. Por que você precisa disso?
henning - reinstala Monica
3
@henning Existem muitas razões possíveis, então essa é uma boa pergunta. Por exemplo, um programa que tenta processar automaticamente arquivos com um nome de arquivo correspondente a um determinado regex (mas não pode ser desabilitado temporariamente por razões burocráticas). Ou talvez um sistema de backup que armazena arquivos e armazena-os em mídia durável, mas somente gravação.
precisa saber é o seguinte
11
@henning Eu preciso disso porque tenho um número de caches lidos em vários armazenamentos diferentes, mas um está chegando à capacidade e precisa ser removido do serviço. Portanto, é necessário que cada arquivo, se existir em qualquer um dos locais, precise estar completo e intacto. Caso contrário, existe uma condição de corrida entre uma transferência que começa e termina em que um cache pode pegar (e reter) um arquivo incompleto.
Niels2000

Respostas:

27

rsynccopia para nomes de arquivos temporários (por exemplo, consulte Extensão de arquivo temporário Rsync e rsync - ele cria um arquivo temporário durante a transferência? ), a menos que você use a --inplaceopção. Ele os renomeia somente depois que o arquivo foi transferido com sucesso. rsynctambém exclui todos os arquivos de destino que foram transferidos apenas parcialmente (por exemplo, devido ao disco cheio ou outro erro).

Há também uma --remove-source-filesopção que exclui o (s) arquivo (s) de origem depois que eles foram transferidos com sucesso. Veja a rsyncpágina de manual para mais detalhes.

Juntando tudo isso, você pode usar algo como:

rsync -ax --remove-source-files source/ target/

Essa opção é particularmente útil para tarefas como mover arquivos de uma fila "de entrada" ou semelhante ao diretório em que serão processados.

Como alternativa, se este for um espelho único, talvez use apenas rsyncsem a --remove-source-filesopção. Você pode excluir os arquivos de origem posteriormente, se desejar / precisar.

cas
fonte
Eu pensei que haveria uma boa ferramenta para o trabalho. Obrigado!
precisa saber é o seguinte
@ Niels2000 Não me lembro se já usei essa opção rsync antes, mas o que você queria parecia o tipo de coisa que rsyncpoderia fazer, e eu sabia que ela transferia arquivos com um nome temporário (a menos que você use --inplace), então procurei em man rsynce encontrou --remove-source-files. rsyncé uma boa ferramenta para verificar primeiro quase todas as tarefas de transferência de arquivos.
cas 22/12