haga que rsync espere una confirmación antes de cambiar realmente los archivos

11

Estoy haciendo una sincronización entre una carpeta local y una remota. Sucedió que perdí un archivo por un comando estúpido.

Estoy acostumbrado a unísono y a la forma en que usted confirma ("¿ir?") Antes de hacer la transferencia de archivos real.

¿Existe tal opción con rsync? (sin unísono en el lado del servidor)

¡Gracias!

Meduz
fuente

Respuestas:

3

En lugar de una opción oficial "--confirmar", se puede aprovechar el propio "modo por lotes" de rsync para evitar tener que calcular dos veces la diferencia entre dos rutas. El modo por lotes estaba destinado a distribuir cambios en los espejos (calcular una vez, actualizar muchos árboles idénticos). Se crean dos archivos: un archivo por lotes que contiene las actualizaciones y un sencillo script de conveniencia para ejecutar la actualización (hay una sección hacia el final de la página del manual de rsync con detalles).

Aquí hay un contenedor de bash para abstraer el proceso:

#!/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

Tenga en cuenta que, dado que este script escribe $TMP_DIR, puede encontrarse con limitaciones de espacio si está moviendo datos realmente grandes (más grandes que su / tmp, por ejemplo).

Steve
fuente
1
¿Esto pide una confirmación para cada archivo?
Muy irregular
2
No, esto calcula los cambios, los muestra y luego muestra un solo mensaje, "¿Continuar (y / N)?" Ha pasado un tiempo desde que usé esto, pero IIRC, rsync todavía parecía recalcular el rdiff.
Steve
7

Puede usar la opción -n con rsync para realizar una ejecución en seco. rsync le dirá qué operaciones habría realizado sin realizarlas realmente. Si está satisfecho con los resultados, vuelva a ejecutar sin la opción -n.

Mike Fitzpatrick
fuente
7

Puede hacer rsync para respaldar archivos al sobrescribir, usando la opción --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)

después de ejecutar rsync, puede escanear el directorio de respaldo en busca de archivos y preguntar uno por uno si necesita restaurarlo.

zb '
fuente
5

Lamentablemente, no existe un método integrado en Rsync en el momento de la escritura.

La solución de Mike Fitzpatrick funcionará bien, sin embargo, si tiene un árbol de directorios muy grande, es posible que desee hacer algo que no haga que rsync vuelva a revisar todos los archivos

EDITAR: También hay un error en el que no se elimina un archivo de destino ... cuanto más lo miro, esta solución se rompe ... Lo dejo porque puede funcionar en su caso y también si alguien quiere arreglarlo. Además, alguien debe enviar una solicitud de función formal a https://bugzilla.samba.org/enter_bug.cgi?product=rsync

Escribí 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
  • Intente pegar el script en un archivo llamado rsync-confirm.bash

  • Entonces chmod +x rsync-confirm.bash

  • Entonces ./rsync-confirm.bash -rvh /etc/ /tmp/etc/

Este script puede ser un poco defectuoso, noté que realmente no le gusta si no tiene una barra diagonal en el directorio de origen ...

Dave Butler
fuente