rsync: ignorer les fichiers pour lesquels je n'ai pas d'autorisations

16

J'utilise rsync -rlptDpour copier un répertoire d'un autre utilisateur. Il y a quelques fichiers (je n'ai aucun moyen de les connaître à l'avance) que je n'ai pas la permission de copier. Existe-t-il un moyen pour que rsync les ignore? Le problème est que si rsync retourne non nul, mon script bash -x se fermera.

JeffCharter
la source
Rsync a des valeurs de sortie bien documentées. Vous ne devriez pas tous les considérer comme un échec si votre situation ne demande pas que ce soit un échec.
jordanm
@jordanm Mais il n'y a pas de code d'erreur suffisamment spécifique pour localiser cette erreur uniquement.
Gilles 'SO- arrête d'être méchant'

Réponses:

7

Rsync n'a pas d'option pour cela. Je vois deux solutions. L'une consiste à analyser les messages d'erreur rsync; ce n'est pas très robuste. L'autre consiste à générer une liste de fichiers illisibles à filtrer.

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"

Si votre findn'a pas -readableet -executable, les remplacer par les appropriée -permdirective.

Cela suppose qu'il n'existe aucun fichier illisible dont le nom contient une nouvelle ligne. Si vous devez y faire face, vous devrez produire une liste de fichiers délimités par des valeurs nuls comme celle-ci et passer l' -0option à rsync:

find . \( ! -readable -o -type d ! -executable \) -print0 |
  perl -0000 -pe 's:\A\./:/:' -e 's:[?*\\[]:$1:g' >>"$exclude_file"
Gilles 'SO- arrête d'être méchant'
la source
C'est probablement son meilleur pari. Heureusement, il n'a besoin de l'exécuter qu'une seule fois, car avoir à stat()chaque fichier deux fois (une fois via rsync et une fois via find) serait assez mauvais.
jordanm
@Gilles cela semble fonctionner, sauf pour les fichiers cachés. Je suppose que la même stratégie fonctionnera avec quelques ajustements mineurs. Je ne connais pas le \! (slash exclamation) pourriez-vous expliquer cela?
JeffCharter
1
@JeffC \!cite l' !opérateur pour le protéger contre l'expansion du shell. La barre oblique inversée n'est pas réellement nécessaire ici car aucun shell ne se dilate !lorsqu'il est suivi d'un espace, mais cela ne fait pas de mal. Quel est le problème avec les fichiers cachés?
Gilles 'SO- arrête d'être méchant'
3

J'ai fait une solution de contournement simple pour cette situation spécifique:

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

Cela renvoie 0si le code renvoyé était 0 ou 23 et renvoie le code de sortie dans tous les autres cas.

Il est important de noter, cependant, que cela ignorerait toutes les Partial transfer due to errorerreurs, pas seulement celles liées aux autorisations , car cela interceptera tout ce qui sort du code 23. Pour plus d'informations sur les codes d'état rsync, veuillez consulter ce lien .

Gus
la source