faça o rsync aguardar uma confirmação antes de realmente alterar os arquivos

11

Estou fazendo uma sincronização entre uma pasta local e uma remota. Aconteceu que eu perdi um arquivo por um comando estúpido.

Estou acostumado a uníssono e à maneira como você confirma ("vai?") Antes de fazer a transferência real do arquivo.

Existe essa opção com o rsync? (sem uníssono no lado do servidor)

Obrigado!

meduz
fonte

Respostas:

3

Em vez de uma opção "--confirm" oficial, o próprio "modo de lote" do rsync pode ser aproveitado para contornar a necessidade de calcular duas vezes a diferença entre dois caminhos. O modo de lote foi projetado para distribuir alterações nos espelhos (calcular uma vez, atualizar muitas árvores idênticas). Dois arquivos são criados: um arquivo em lotes contendo as atualizações e um script de conveniência simples para executar a atualização (há uma seção no final da página de manual do rsync com detalhes).

Aqui está um invólucro do bash para abstrair o processo:

#!/bin/bash

cleanup ()
{
    rm ${BFILE} ${BFILE}.sh &>/dev/null
}

# generate tmpfile
BFILE=$( mktemp )

# rsync command
if ! rsync --only-write-batch="${BFILE}" --verbose "$@"; then
    cleanup
    exit 1
fi

# confirmation
read -p "Continue (y/N)? " confirm
if [ "$confirm" != "y" ]; then
    echo "Aborting"
    cleanup
    exit 1
fi

# carve up arguments
dest="${@: -1}"         # last argument
host="${dest%%:*}"      # host:path
path="${dest#*:}"
opts="${@:1:$(($#-2))}" # everything but the last two args
if [ "$host" = "${path}" ]; then
    # local
    sh "${BFILE}.sh"
else
    # remote
    ssh "$host" rsync --read-batch=- "${opts}" "${path}" <"${BFILE}"
fi

cleanup

Observe que, desde que esse script é gravado $TMP_DIR, você pode ter restrições de espaço se estiver movendo realmente grandes dados (maiores que seu / tmp, por exemplo).

Steve
fonte
11
Isso pede uma confirmação para cada arquivo?
Altamente irregular
2
Não, isso calcula as alterações, as exibe e, em seguida, exibe um único prompt, "Continuar (s / N)?" Faz algum tempo desde que eu usei isso, mas o IIRC, rsync ainda parecia recalcular o rdiff.
31315 Steve
7

Você pode usar a opção -n com o rsync para executar uma execução a seco. O rsync lhe dirá quais operações ele executaria sem realmente executá-las. Se você estiver satisfeito com os resultados, execute novamente sem a opção -n.

Mike Fitzpatrick
fonte
7

Você pode fazer o rsync fazer backup dos arquivos sobrescrevendo, usando a opção --backup,

 -b, --backup                make backups (see --suffix & --backup-dir)
     --backup-dir=DIR        make backups into hierarchy based in DIR
     --suffix=SUFFIX         backup suffix (default ~ w/o --backup-dir)

após a execução do rsync, você pode verificar se há arquivos de backup-dir e perguntar um por um se eles precisam ser restaurados.

zb '
fonte
5

Infelizmente, ainda não existe um método incorporado no Rsync.

A solução de Mike Fitzpatrick funcionará bem, no entanto, se você tiver uma árvore de diretórios muito grande, poderá fazer algo que não faça o rsync passar por todos os arquivos novamente

EDIT: Há também um erro em que ele não exclui um arquivo de destino ... quanto mais eu olho para ele, esta solução está quebrada ... Estou deixando de lado porque pode funcionar no seu caso e também se alguém quiser para fixar isso. Além disso, alguém deve enviar uma solicitação formal de recurso para https://bugzilla.samba.org/enter_bug.cgi?product=rsync

Eu escrevi este script:

#! /bin/bash

# Make a temp file for storing the output of rsync

tmpfile=$( mktemp )  &&

# Do all the hard work ( get the list of files we need to update ), 
#  but dont actually change the filesystem

rsync --dry-run --out-format='RSYNC_CONFIRM %i %n%L' "$@" | grep RSYNC_CONFIRM | awk '{ print $3 }' > $tmpfile &&


# Output to the user what we propose to do
rsync --dry-run --itemize-changes --files-from=$tmpfile "$@" &&

# Alternatively, we could just output $tmpfile... but whatever...

read -p "Continue? (y/n)?" &&

if [[ $REPLY = [yY] ]]
then
{
  rsync --files-from=$tmpfile "$@"
}
fi

rm $tmpfile
  • Tente colar o script em um arquivo chamado rsync-confirm.bash

  • Então chmod +x rsync-confirm.bash

  • Então ./rsync-confirm.bash -rvh /etc/ /tmp/etc/

Esse script pode ser um pouco complicado, notei que ele realmente não gosta se você não tiver uma barra no diretório de origem ...

Dave Butler
fonte