aPugLife
aPugLife

Reputation: 1039

rsync --exclude 'folder', copies that folder anyway

There are a lot of posts about this, I know, but I tried all and still can't get it working.

If this is my folder to backup: /home/user/thingstobackup the script will create a "backup" folder here and inside another folder named as the date of today. The daily backup is copied inside.

No matter how I use rsync, the "backup" folder will be always copied inside itself starting from the 2nd run of the script.

1st run:

/home/user/thingstobackup
/home/user/thingstobackup/backup/2016-01-13 #and correct file inside

2nd run:

/home/user/thingstobackup/backup/2016-01-13 #with correct file inside
/home/user/thingstobackup/backup/2016-01-14 #with correct file inside

I will shorten the path here..

../backup/2016-01-14/2016-01-13/and backed up file inside..
../backup/2016-01-14/backup/
../backup/2016-01-14/backup/2016-01-13/and backed up file inside..
../backup/2016-01-14/backup/2016-01-14/empty

After the 2nd run, the backup folder is copied inside every daily backup folder.

The script:

#!/bin/bash

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

# directory to backup
TOSAVE=/home/user/thingstobackup
TODAY=`date +%F`
BDIR=backup
BACKUPDIR=$TOSAVE/$BDIR/$TODAY/

# options for rsync
OPTS="-aq --exclude='backup/*'"

# find daily new file
FIND="`find $TOSAVE -mindepth 1 -mtime -1 -print`"

# MAIN #

# copy daily found inside new created daily folder
[ -d $TOSAVE/$BDIR/$TODAY ] || mkdir -p $TOSAVE/$BDIR/$TODAY
rsync $OPTS $FIND $BACKUPDIR

# delete file older than 2 weeks = 14 days
find $TOSAVE -mtime +14 -exec rm -rf {} \;

No matter how I use --exclude='backup/*'" --exclude='backup' || --exclude 'backup/*' || --exclude 'backup'

It does not exclude that folder.. Yes I read the rsync manual: --exclude=PATTERN exclude files matching PATTERN

I'm sure I'm missing something but I just can't find it! Thanks in advance mates

Upvotes: 1

Views: 1036

Answers (3)

l'L'l
l'L'l

Reputation: 47169

You should be able to fix the --exclude issue by not putting quotes around the option or by including a space instead of using =; rsync is very particular about how options are written:

--exclude=backup

alternative:

--exclude '*dir'

Other Suggestions:

  1. Remove trailing slashes on variables (rsync is very specific about /)
  2. For command subsitution use $( ... ) instead of backticks (if available/possible)
  3. Eliminate redundant code (eg. you define $BACKUPDIR but only use it once effectively)
  4. When having issues always use the --verbose option, it really helps with rsync

Revised Script:

#!/bin/env bash

# export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

# directory to backup
TOSAVE=$HOME/thingstobackup
TODAY=$(date +%F)
BDIR=backup
BACKUPDIR=$TOSAVE/$BDIR/$TODAY

# options for rsync
OPTS="-raq --exclude=$BDIR --exclude=$TODAY"

# find daily new file
FIND=$(find $TOSAVE -mindepth 1 -mtime -1 -print)

# MAIN #
# copy daily found inside new created daily folder
[ -d $BACKUPDIR ] || mkdir -p $BACKUPDIR
rsync $OPTS $FIND $BACKUPDIR

# delete file older than 2 weeks = 14 days
find $TOSAVE -mtime +14 -exec rm -rf {} \;

Most of the changes are in the way the paths are constructed forthingstobackup:

file1
file2
file3

Running the script it would then appear like:

file1   
file2   
file3   // files that will be included to rsync destination
|
|_______backup   // exclude=$BDIR should not be included
        |
        |________2016-01-14   // exlude=$TODAY would also be advised
                  file1
                  file2
                  file3

EDIT: In order for rsync to not break when encountering a filename containing spaces you'll want to handle that in your find method. * You could likely refine your script further by using rsync commands instead of find altogether, but I'll leave that up to you.

Upvotes: 0

l0b0
l0b0

Reputation: 58788

@Nihvel was right:

cd -- "$(mktemp --directory)"
mkdir foo bar
touch foo/foo bar/bar
other="$(mktemp --directory)"
rsync --recursive --exclude 'foo' * "$other"
ls "$other" # prints only "bar"

This works whether the local file specifier is * (as above), ./* or /tmp/tmp.MGUbytm0h0/*, and whether $PWD is /tmp/tmp.MGUbytm0h0 or something else.

Upvotes: 0

aPugLife
aPugLife

Reputation: 1039

I do not know why --exclude does not work here.. but I modified the find command and I managed to let this thing work.

FIND="`find $TOSAVE -mindepth 1 -type d \( -path $TOSAVE/backup \) -prune -o -mtime -1 -print`"

Upvotes: 0

Related Questions