Mover arquivos (não copiar) de forma confiável sobre o ssh

1

Eu quero mover um grande número de arquivos grandes em ssh.

Como desejo liberar espaço, desejo excluir os arquivos depois que eles forem movidos. Como a quantidade de dados é grande, eu quero poder interromper a transferência a qualquer momento e continuar com o mesmo comando mais tarde. (Na verdade, minha conexão com a internet é redefinida pelo menos uma vez por dia e interrompe a transferência)

Infelizmente, não consigo usar o rsync, pelo menos não assim:

rsync -avz --remove-source-files user@source:/path/ /destination_path/

O rsync exclui apenas os arquivos de origem após TODOS terem sido copiados - se a transferência for interrompida, nenhum espaço será liberado. Colocar o comando no cron fará com que ele nunca termine sem excluir manualmente os arquivos que já foram copiados.

Existe uma solução para este problema?

    
por Roland Seuhs 06.06.2018 / 19:16

2 respostas

3

Se você não puder usar rsync e quiser remover os arquivos de origem somente após cada arquivo ter sido copiado com sucesso, poderá fazer algo assim para um diretório por diretório, transferência arquivo a arquivo:

if cd /path/to/files; then
for file in *; do
    if scp -pr "$file" [email protected]:/destination/files/"$file"; then
        rm -fr "$file"
    else
        echo "Transfer of '$file' failed.  Not removing local copy." 1>&2
    fi
done; fi

Se você quiser fazer uma verificação de sanidade adicional antes de excluir o arquivo local, adicione uma verificação de consistência, mas isso reduzirá a velocidade de arquivos muito grandes, e essa soma de verificação rápida e suja só funcionará em arquivos ; não diretórios:

if cd /path/to/files; then
for file in *; do
    if scp -pr "$file" [email protected]:/destination/files/"$file"; then
        if [[ "$(md5sum < "$file" )" = "$( ssh [email protected] md5sum < /destination/files/"$file" )" ]]; then
            rm -fr "$file"
        else
            echo "Unable to validate remote '$file'.  Not removing local copy" 1>&2
        fi
    else
        echo "Transfer of '$file' failed.  Not removing local copy." 1>&2
    fi
done; fi
    
por 06.06.2018 / 19:28
1

rsync only deletes the source files after ALL have been copied

Esta é uma premissa falsa. Pode parecer verdade quando você tem apenas alguns arquivos grandes, mas certamente não é verdade no caso geral.

O comando rsync enfileira uma instrução de exclusão assim que um arquivo é transferido com êxito. No entanto, como as instruções são multiplexadas com outros dados, pode levar "um tempo" para que a exclusão seja aplicada no lado da origem.

Se você executar rsync com um grande número de arquivos, verá os arquivos serem excluídos na origem antes que todas as transferências tenham sido concluídas. (Eu corro rsync com dezenas ou mesmo centenas de milhares de arquivos em uma sessão e vejo esse comportamento.)

Além disso, se você tiver um cenário em que uma transferência é interrompida, quando o rsync for reiniciado, ele excluirá os arquivos transferidos anteriormente com êxito antes de passar para o próximo conjunto de arquivos a serem transferidos. (Eu também vejo esse comportamento.)

Considere o link para referência ao código fonte como evidência.

    
por 07.06.2018 / 00:51

Tags