faire en sorte que rsync attende une confirmation avant de modifier réellement les fichiers

11

Je fais une synchronisation entre un dossier local et un dossier distant. Il m'est arrivé de perdre un fichier par une stupide commande.

Je suis habitué à l'unisson et à la façon dont vous confirmez ("allez?") Avant de faire le transfert de fichier proprement dit.

Existe-t-il une telle option avec rsync? (pas d'unisson côté serveur)

Merci!

meduz
la source

Réponses:

3

Au lieu d'une option officielle "--confirm", le "mode batch" de rsync peut être utilisé pour contourner le fait d'avoir à calculer deux fois la différence entre deux chemins. Le mode batch était destiné à distribuer les modifications aux miroirs (calculer une fois, mettre à jour de nombreuses arborescences identiques). Deux fichiers sont créés: un fichier batch contenant les mises à jour et un simple script de commodité pour exécuter la mise à jour (il y a une section vers la fin de la page de manuel rsync avec des détails).

Voici un wrapper bash pour résumer le processus:

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

Notez que puisque ce script écrit $TMP_DIR, vous pouvez rencontrer des contraintes d'espace si vous déplacez de très grandes données (plus grandes que votre / tmp, par exemple).

Steve
la source
1
Est-ce que cela demande une confirmation pour chaque fichier?
Très irrégulier
2
Non, cela calcule les modifications, les affiche, puis affiche une seule invite, "Continuer (o / N)?" Cela fait un moment que je ne l'ai pas utilisé, mais IIRC, rsync semblait toujours recalculer le rdiff.
Steve
7

Vous pouvez utiliser l'option -n avec rsync pour effectuer un essai à sec. rsync vous indiquera les opérations qu'il aurait effectuées sans les effectuer. Si vous êtes satisfait des résultats, réexécutez sans l'option -n.

Mike Fitzpatrick
la source
7

Vous pouvez faire rsync pour sauvegarder des fichiers lors de l'écrasement, en utilisant l'option --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)

après l'exécution de rsync, vous pouvez analyser le répertoire de sauvegarde pour les fichiers et demander un par un s'il doit être restauré.

zb '
la source
5

Malheureusement, il n'y a pas de méthode intégrée dans Rsync au moment de l'écriture.

La solution de Mike Fitzpatrick fonctionnera bien, mais si vous avez une très grande arborescence de répertoires, vous voudrez peut-être faire quelque chose qui ne fera pas rsync parcourir à nouveau tous les fichiers

EDIT: Il y a aussi un bug où il ne supprimera pas un fichier de destination ... de plus en plus je le regarde, cette solution est cassée ... Je le laisse en place car cela peut fonctionner dans votre cas et aussi si quelqu'un veut réparer. En outre, quelqu'un doit soumettre une demande de fonctionnalité officielle à https://bugzilla.samba.org/enter_bug.cgi?product=rsync

J'ai écrit ce 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
  • Essayez de coller le script dans un fichier appelé rsync-confirm.bash

  • alors chmod +x rsync-confirm.bash

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

Ce script pourrait être un peu bogué, j'ai remarqué qu'il ne l'aime pas vraiment si vous n'avez pas de barre oblique dans le répertoire source ...

Dave Butler
la source