rsync: Dateien überspringen, für die ich keine Berechtigungen habe

16

Ich benutze, rsync -rlptDum ein Verzeichnis von einem anderen Benutzer zu kopieren. Es gibt einige Dateien (ich habe keine Möglichkeit, diese im Voraus zu kennen), die ich nicht kopieren darf. Gibt es eine Möglichkeit, rsync diese zu ignorieren. Das Problem ist, dass mein Bash-x-Skript beendet wird, wenn rsync einen Wert ungleich Null zurückgibt.

JeffCharter
quelle
Rsync hat gut dokumentierte Exit-Werte. Sie sollten nicht alle als Fehler behandeln, wenn Ihre Situation keinen Fehler erfordert.
Jordan
@jordanm Es gibt jedoch keinen Fehlercode, der spezifisch genug ist, um nur diesen Fehler zu lokalisieren.
Gilles 'SO- hör auf böse zu sein'

Antworten:

7

Rsync hat dafür keine Option. Ich sehe zwei Lösungen. Eine besteht darin, rsync-Fehlermeldungen zu analysieren. das ist nicht sehr robust. Die andere Möglichkeit besteht darin, eine Liste mit nicht lesbaren Dateien zu erstellen, die gefiltert werden sollen.

cd /source/directory
exclude_file=$(mktemp)
find . ! -readable -o -type d ! -executable |
  sed -e 's:^\./:/:' -e 's:[?*\\[]:\\1:g' >>"$exclude_file"
rsync -rlptD --exclude-from="$exclude_file" . /target/directory
rm "$exclude_file"

Wenn Ihr findnicht über -readableund -executableersetzen Sie sie durch die entsprechende -permRichtlinie.

Dies setzt voraus, dass keine unlesbaren Dateien vorhanden sind, deren Name eine neue Zeile enthält. Wenn Sie mit solchen Problemen fertig werden müssen, müssen Sie eine durch Nullen getrennte Dateiliste wie diese erstellen und die -0Option übergeben an rsync:

find . \( ! -readable -o -type d ! -executable \) -print0 |
  perl -0000 -pe 's:\A\./:/:' -e 's:[?*\\[]:$1:g' >>"$exclude_file"
Gilles 'SO - hör auf böse zu sein'
quelle
Dies ist wahrscheinlich seine beste Wette. Hoffentlich muss er dies nur einmal ausführen, da es stat()ziemlich schlecht wäre , jede Datei zweimal (einmal per rsync und einmal per find) zu haben.
Jordan
@ Gilles das scheint zu funktionieren, außer für versteckte Dateien. Ich gehe davon aus, dass die gleiche Strategie mit einigen geringfügigen Optimierungen funktionieren wird. Ich bin nicht vertraut mit dem \! (Ausrufezeichen) Können Sie das erklären?
JeffCharter
1
@JeffC \!zitiert den !Operator, um ihn vor Shell-Erweiterung zu schützen. Der Backslash ist hier eigentlich nicht notwendig, da sich keine Shell ausdehnt, !wenn ein Leerzeichen folgt, aber es tut nicht weh. Was ist los mit versteckten Dateien?
Gilles 'SO- hör auf böse zu sein'
2

Ich habe eine einfache Lösung für diese spezielle Situation gefunden:

rsync --args || $(case "$?" in 0|23) exit 0 ;; *) exit $?; esac)

Dies gibt zurück, 0wenn der zurückgegebene Code 0 oder 23 war, und gibt in allen anderen Fällen den Exit-Code zurück.

Es ist jedoch wichtig zu beachten, dass dies alle Partial transfer due to errorFehler ignorieren würde , nicht nur die der Erlaubnis , da alles abgefangen wird, was den Code verlässt 23. Weitere Informationen zu den rsync-Statuscodes finden Sie unter diesem Link .

Gus
quelle