To get the DOS attributes into Linux you will need to edit your smb.conf file.
There are two different ways to import Windows attributes.
The first option is to set map hidden = yes
which will mean that hidden files on Windows will have the world execute bit set on Linux. For this to work you must also have at least 001
in your create mask
.
The other option is to set store dos attributes = yes
which will mean that the Windows attributes will be stored in an extended attribute in the Linux file system called user.DOSATTRIB.
rsync
doesn't have the ability to filter files based on either normal or extended attributes but it can exclude a list of files that you have prepared in some other way. You can use the find
command to create this list based on Unix attributes. The version of find
I have doesn't seem to support extended attributes but it might still be possible to use the -exec
option in find
to get extended attributes of all your files and filter on them.
Since find
can filter on normal Unix permissions, if you chose the world execute bit option then find . -perm -001
will find all of the hidden files in your mounted Windows filesystem. You can put this list in a file and then use rsync --exclude-from=FILE
to exclude those files from your rsync.
If you can trust the filesystem last-modified timestamps, you can speed things up by combining Rsync with the UNIX/Linux 'find' utility. 'find' can assemble a list of all files that show last-modified times within the past day, and then pipe ONLY that shortened list of files/directories to Rsync. This is much faster than having Rsync compare the metadata of every single file on the sender against the remote server.
In short, the following command will execute Rsync ONLY on the list of files and directories that have changed in the last 24 hours: (Rsync will NOT bother to check any other files/directories.)
find /local/data/path/ -mindepth 1 -ctime -0 -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
In case you're not familiar with the 'find' command, it recurses through a specific directory subtree, looking for files and/or directories that meet whatever criteria you specify. For example, this command:
find . -name '\.svn' -type d -ctime -0 -print
will start in the current directory (".") and recurse through all sub-directories, looking for:
- any directories ("-type d"),
- named ".svn" ("-name '.svn'"),
- with metadata modified in the last 24 hours ("-ctime -0").
It prints the full path name ("-print") of anything matching those criteria on the standard output. The options '-name ', '-type ', and '-ctime ' are called "tests", and the option '-print' is called an "action". The man page for 'find' has a complete list of tests and actions.
If you want to be really clever, you can use the 'find' command's '-cnewer ' test, instead of '-ctime ' to make this process more fault-tolerant and flexible. '-cnewer' tests whether each file/directory in the tree has had its metadata modified more recently than some reference file. Use 'touch' to create the NEXT run's reference file at the beginning of each run, right before the 'find... | rsync...' command executes. Here's the basic implementation:
#!/bin/sh
curr_ref_file=`ls /var/run/last_rsync_run.*`
next_ref_file="/var/run/last_rsync_run.$RANDOM"
touch $next_ref_file
find /local/data/path/ -mindepth 1 -cnewer $curr_ref_file -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
rm -f $curr_ref_file
This script automatically knows when it was last run, and it only transfers files modified since the last run. While this is more complicated, it protects you against situations where you might have missed running the job for more than 24 hours, due to downtime or some other error.
Best Answer
You can use rsync filters to specify which subpaths you want transferred:
This will create all the source directories on the destination (but not containing any files). To not do this you need to explicitly include all parent directories:
Edit: To exclude files with a certain extension, add an
--exclude
pattern at the front: