How to skip special / socket files during rsync transfer

backupdevicesrsyncspecial characters

Using the following command.

rsync --archive --delete --partial --progress --recursive --no-links --no-devices --quiet source target

Using --no-links and --no-devices already.

Getting the error messages such as this.

rsync: mknod "/mnt/shared/backup/var/spool/postfix/dev/log" failed: Operation not permitted (1)

Makes rsync exit non-zero. This is bad. Breaks my backup script. (I don't want to use ignore this error using || true in case rsync would fail for "legitimate" reasons such as no disk space left.)

In this example, it's a socket file. I don't care about this kind of special files. Can I make rsync ignore/skip those?

Best Answer

rsync -a --no-specials --no-devices would tell rsync to skip these files. It will still print an information message, but it would return 0 if no other error occurs.

If there's a set of known paths that you don't want to transfer, you could exclude them altogether. Also, do pass the -x option to skip all mounted filesystems (including /dev, which takes care of the biggest offender), and if there are multiple on-disk filesystems, list all the mount points (e.g. rsync -ax / /home /destination).

rsync -ax --exclude='/var/spool/postfix/dev/*' / /mnt/shared/backup

If none of that is satisfactory, make a list of files you want to skip. Beware that if some of the file names are under control of an adversary, they could cause some files to be omitted from a backup. For example, if they create a directory whose name is a newline and create a named socket called * inside it, then using the output of find -type s as an exclude list would result in /* being excluded. To prevent such problems, keep problematic names out of the exclude list.

{
  cd /path/to/source &&
  find . -name '*[\[?*
]*' -prune -o \
               \( -type b -o -type c -o -type p -o -type s \) -print |
  sed 's/^\.//'
} | rsync -a --exclude-from=- /path/to/source /destination
Related Question