rsync exclude files depending on --exclude position - rsync

I have a simple rsync script for sync source and test files:
rsync -a --include '*/' --include '*.hpp' --include '*.cpp' --include "Test/*" --exclude 'main.cpp' --exclude 'makefile' --exclude '*' --progress . somewhere/
While it correctly excludes makefile it does not exclude main.cpp, while doing this:
rsync -a --include '*/' --exclude 'main.cpp' --include '*.hpp' --include '*.cpp' --include "Test/*"--exclude 'makefile' --exclude '*' --progress . somewhere/
Seems to work. Why?

From the man page:
As the list of files/directories to transfer is built, rsync checks each name to be transferred against the list of include/exclude patterns in turn, and the first matching pattern is acted on: if it is an exclude pattern, then that file is skipped; if it is an include pattern then that filename is not skipped; if no matching pattern is found, then the filename is not skipped.
So if you want main.cpp to be excluded, you need to have an --exclude pattern which matches main.cpp before any --include patterns which match it.
If you're using --filter, the same applies to that too. Actually --include and --exclude are just shorthand for certain kinds of --filter rules.

Related

Rsync exclude correct syntax

I want to copy a directory from remote machine to local using rsync, but without some inner folders.
I'm using this command:
rsync -rave --exclude 'js' --exclude 'css' --exclude 'fonts' root#{IP}:/rem_dir1/rem_dir2/public /local_dir1/local_dir2/public
But result of it is:
Unexpected remote arg: root#{IP}:/rem_dir1/rem_dir2/public
rsync error: syntax or usage error (code 1) at main.c(1361) [sender=3.1.2]
I'm sure remote root is correct. So the problem is in rsync command syntax.
What is the correct way to exclude several folders using rsync?
For example we have /public folder which contains dir1, dir2, dir3, dir4 and dir5. How to copy only dir1 and dir2 from /public?
As with your other question, the -rave makes no sense. You want just -av.
You can get fancy with include and exclude commands, but the easiest way to copy just two directories is just to list them:
rsync -av \
root#{IP}:/rem_dir1/rem_dir2/public/dir1 \
root#{IP}:/rem_dir1/rem_dir2/public/dir2 \
/local_dir1/local_dir2/public/
where \ is just line-continuation (so I can wrap the long line), and I deliberately only added / to the end of the destination path, not the source paths.

How to exclude hidden file ".htaccess" in rsync?

I want to exclude one special hidden file in just one special folder.
The command I used is:
rsync -a --delete \
--exclude='/absolute/path/to/webpage/folder1' \
--exclude='/absolute/path/to/webpage/backups' \
--exclude='/absolute/path/to/webpage/.htaccess' \
/absolute/path/to/webpage/ \
/absolute/path/to/copy_of_webpage &>/dev/null
rsync always overwrites my .htaccess.
Also I want to keep my .htpasswd and I thought about using wildcards like:
rsync -a --delete \
--exclude='/absolute/path/to/webpage/folder1' \
--exclude='/absolute/path/to/webpage/backups' \
--exclude='/absolute/path/to/webpage/.ht*' \
/absolute/path/to/webpage/ \
/absolute/path/to/copy_of_webpage &>/dev/null
But that doesn't work either.
You could exclude all .htaccess with --exclude '.htaccess'
Exclude the path relative to the source folder, not the absolute path.
If your root (as above) is:
/absolute/path/to/webpage/
and you wish to exclude:
/absolute/path/to/webpage/.htaccess
/absolute/path/to/webpage/backups
then you'll need to say:
--exclude='/.htaccess' --exclude='/backups'
Per the docs:
"/foo" would match a file called "foo" at... the "root of the transfer"

Rsync failing with Env Variable

I am using following script to rsync back files. If I amy execute those one by one on shell it work. But when I use to execute theem in script it is giving error
"rsync: link_stat "/home/tan/testnfs#015" failed: No such file or directory (2)"
015 is no where in script, I have edited the script and verify that no blank space or character left. But have same problem.
#!/bin/bash
#========================================
#Environment varibale settings
#========================================
username=test
codedir=/home/tan/testnfs
nfs=10.100.200.4::test
adminemail=backup#tan.com
errorlog=/home/tan/backuperror_log.txt
dat=$(date)
rm -fr $errorlog
echo $dat 2>&1>> $errorlog
echo $nfsserver
echo ========== Before rsync =================
rsync --stats -vr --exclude "*.png" --exclude "*.jpg" --exclude "*.jpeg" --exclude "*.zip" --exclude "*.pdf" --exclude "*.doc" --exclude "*.csv" --exclude "*.swf" $codedir $nfs
if [ $? = 0 ] then
mail -s "$username sync--complete" $adminemail < $errorlog
else
mail -s "$username sync--Incomplete" $adminemail < $errorlog
fi
I had figure that out. I was editing script on windows and it was adding its line terminator. I have saved it as linux file with notepad++ and it worked

rsync only *.php files

How can I rsync mirror only *.php files? This gives me a bunch of empty dirs too and I don't want those.
rsync -v -aze 'ssh ' \
--numeric-ids \
--delete \
--include '*/' \
--exclude '*' \
--include '*.php' \
user#site.com:/home/www/domain.com \
/Volumes/Servers/
The culprit here is the
--include '*/'
When including a wildcard followed by the trailing forward-slash you're telling rsync to transfer all files ending with a '/' (that is, all directories).
Thus,
rsync -v -aze 'ssh ' \
--numeric-ids \
--delete \
--exclude '*' \
--include '*.php' \
user#site.com:/home/www/domain.com \
/Volumes/Servers/
If you were using that because you intend to recursively find all .php files, you’d have to use the ** wildcard.
That is,
--include '**/*.php'
Another way ( http://www.commandlinefu.com/commands/view/1481/rsync-find ) is pre-finding the target files and then using rsync,
find source -name "*.php" -print0 | rsync -av --files-from=- --from0 ./ ./destination/

Local rsync inclusion/exclusion

I can't seem to get the command to backup /etc/php5, /etc/apache2 and /etc/mysql right. I'm using two since I couldn't figure out how to do both in one. The first one works:
rsync -vahtl --dry-run --log-file=$LOGFILE --exclude="wp-includes/" --exclude="wp-admin/" --exclude="wp-*.php" /var/www $DROPBOX_FOLDER
But when I run the second, I tried a bunch of --include and --exclude directives variation and nothing works:
rsync -vahtl --dry-run --log-file=$LOGFILE --include="php5" --exclude="*" /etc $DROPBOX_FOLDER
rsync -vahtl --dry-run --log-file=$LOGFILE --include="*/" --include="php5/" --exclude="*" /etc $DROPBOX_FOLDER
etc..
The quickest way is to run it as a bash script using something like this.Would need to be adjusted to your Linux flavor
#!/bin/sh
# rsync backup script
rsync -avz --delete-excluded --exclude-from=backup.lst / /home/USERNAME/Dropbox/backup
Then make a file called backup.lst in the directory in which you will run the script from
# Include
+ /etc/php5
+ /etc/apache2
+ /etc/mysql
+ /var/www
# Exclude
- /var/www/wp-admin/*
- /var/www/wp-*.php
- /var/www/wp-includes/*
- /etc/*
- /run/*
- /proc/*
- /sys/*
- /tmp/*
- lost+found/
- /media/*
- /mnt/*
Here are some exclude/include examples:
# --exclude "*.o" would exclude all filenames matching *.o
# --exclude "/foo" would exclude a file in the base directory called foo
# --exclude "foo/" would exclude any directory called foo.
# --exclude "/foo/*/bar" would exclude any file called bar two levels below a
base directory called foo.
# --exclude "/foo/**/bar" would exclude any file called bar two or more levels below
a base directory called foo.
# --include "*/" --include "*.c" --exclude "*"
would include all directories
and C source files
# --include "foo/" --include "foo/bar.c" --exclude "*"
would include only foo/bar.c (the foo/ directory must be
explicitly included or it would be excluded by the "*")

Resources