I'm using rsync -rlptD to copy a directory from another user. There are a few files (I have no way of knowing these in advance) which I don't have permission to copy. Is there a way have rsync ignore these. The trouble is that if rsync return non-zero my bash -x script will exit.

  • Rsync has well documented exit values. You shouldn't treat all of them as a failure if your situation doesn't call for it to be a failure.
    – jordanm
    Feb 1 '13 at 23:15
  • 2
    @jordanm But there's no error code that's specific enough to pinpoint this error only. Feb 2 '13 at 0:24

Rsync doesn't have an option for this. I see two solutions. One is to parse rsync error messages; this isn't very robust. The other is to generate a list of unreadable files to filter.

cd /source/directory
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"

If your find doesn't have -readable and -executable, replace them by the appropriate -perm directive.

This assumes that there are no unreadable files whose name contains a newline. If you need to cope with those, you'll need to produce a null-delimited file list like this, and pass the -0 option to rsync:

find . \( ! -readable -o -type d ! -executable \) -print0 |
  perl -0000 -pe 's:\A\./:/:' -e 's:[?*\\[]:$1:g' >>"$exclude_file"
  • This is probably his best bet. Hopefully, he only needs to run this once, as having to stat() every file twice (once via rsync and once via find) would be pretty bad.
    – jordanm
    Feb 2 '13 at 3:37
  • @Gilles this seems to work, except for hidden files. I'm assuming the same strategy will work with some minor tweaking. I'm not familiar with the \! (slash exclamation) could you explain that? Feb 4 '13 at 5:23
  • 1
    @JeffC \! quotes the ! operator to protect it against shell expansion. The backslash isn't actually necessary here since no shell expands ! when it's followed by a space, but it doesn't hurt. What's wrong with hidden files? Feb 4 '13 at 9:31

I made a simple workaround for this specific situation:

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

This returns 0 if the returned code was 0 or 23, and returns the exit code in all other cases.

It is important to note, however, that this would ignore all Partial transfer due to error errors, not just permission ones, since it will catch everything that exits code 23. For more information about rsync status codes please refer to this link.

  • 1
    rsync should add more error codes. 23 is used for permission errors, partial transfers and if the source path is completely wrong.
    – mgutt
    Nov 4 '20 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.