Lassen Sie rsync auf eine Bestätigung warten, bevor Sie Dateien tatsächlich ändern

11

Ich mache eine Synchronisation zwischen einem lokalen und einem entfernten Ordner. Es ist passiert, dass ich eine Datei durch einen dummen Befehl verloren habe.

Ich bin es gewohnt, vor der eigentlichen Dateiübertragung zu vereinheitlichen und zu bestätigen, wie Sie bestätigen ("go?").

Gibt es eine solche Option mit rsync? (keine Übereinstimmung auf der Serverseite)

Vielen Dank!

meduz
quelle

Antworten:

3

Anstelle einer offiziellen Option "--confirm" kann der "Batch-Modus" von rsync genutzt werden, um zu umgehen, dass die Differenz zwischen zwei Pfaden zweimal berechnet werden muss. Der Stapelmodus war für die Verteilung von Änderungen an Spiegeln vorgesehen (einmal berechnen, viele identische Bäume aktualisieren). Es werden zwei Dateien erstellt: eine Batch-Datei mit den Updates und ein einfaches Skript zum Ausführen des Updates (am Ende der rsync-Manpage befindet sich ein Abschnitt mit Details).

Hier ist ein Bash-Wrapper zum Abstrahieren des Prozesses:

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

Beachten Sie, dass beim Schreiben dieses Skripts $TMP_DIRmöglicherweise Platzbeschränkungen auftreten, wenn Sie wirklich große Datenmengen verschieben (z. B. größer als Ihr / tmp).

Steve
quelle
1
Fordert dies eine Bestätigung für jede Datei an?
Sehr unregelmäßig
2
Nein, dies berechnet die Änderungen, zeigt sie an und zeigt dann eine einzelne Eingabeaufforderung an: "Weiter (J / N)?" Es ist schon eine Weile her, seit ich das benutzt habe, aber IIRC, rsync schien den rdiff immer noch neu zu berechnen.
Steve
7

Sie können die Option -n mit rsync verwenden, um einen Trockenlauf durchzuführen. rsync teilt Ihnen mit, welche Vorgänge es ausgeführt hätte, ohne sie tatsächlich auszuführen. Wenn Sie mit den Ergebnissen zufrieden sind, führen Sie sie ohne die Option -n erneut aus.

Mike Fitzpatrick
quelle
7

Mit der Option --backup können Sie rsync zum Sichern von Dateien beim Überschreiben ausführen.

 -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)

Nach dem Ausführen von rsync können Sie das Sicherungsverzeichnis nach Dateien durchsuchen und nacheinander fragen, ob es wiederhergestellt werden muss.

Zum Beispiel'
quelle
5

Leider gibt es zum Zeitpunkt des Schreibens keine eingebaute Methode in Rsync.

Die Lösung von Mike Fitzpatrick funktioniert einwandfrei. Wenn Sie jedoch einen sehr großen Verzeichnisbaum haben, möchten Sie möglicherweise etwas tun, bei dem rsync nicht alle Dateien erneut durchläuft

BEARBEITEN: Es gibt auch einen Fehler, bei dem eine Zieldatei nicht gelöscht wird. Je mehr ich sie mir anschaue, desto mehr ist diese Lösung kaputt. Ich lasse sie offen, weil sie in Ihrem Fall möglicherweise funktioniert und auch, wenn jemand dies wünscht etwas reparieren. Außerdem sollte jemand eine formelle Funktionsanforderung an https://bugzilla.samba.org/enter_bug.cgi?product=rsync senden

Ich habe dieses Skript geschrieben:

#! /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
  • Versuchen Sie, das Skript in eine Datei mit dem Namen einzufügen rsync-confirm.bash

  • Dann chmod +x rsync-confirm.bash

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

Dieses Skript ist möglicherweise ein wenig fehlerhaft. Ich habe festgestellt, dass es nicht wirklich gefällt, wenn das Quellverzeichnis keinen abschließenden Schrägstrich enthält.

Dave Butler
quelle