How to exclude a specific directory from being copied by rsync?

87 Views Asked by At

I have the following line that is part of a bash script to copy a website but I want to add to it to exclude one directory website.com/_archive. How do I do this?

rsync -a --info=progress2 --no-i-r ~/website.com ~/tmp/"$projectName"/www

The previous line has been functioning. I am just trying to exclude a directory.

2

There are 2 best solutions below

4
kzi On

You want to use the option --exclude so your command looks like this:

rsync -a --info=progress2 --no-i-r ~/website.com ~/tmp/"$projectName"/www --exclude=/website.com/_archive/

This will also copy the directory website.com into the directory ~/tmp/"$projectName"/www. If you only want to copy the content without the containing directory, use

rsync -a --info=progress2 --no-i-r ~/website.com/ ~/tmp/"$projectName"/www --exclude=/_archive/

Note the additional slash after ~/website.com and the changed exclude-option. The exclude-option should contain an anchored path (starting with /) which is relative to the entry point ~/website.com or ~/website.com/. An exclude option that doesn't start with /, excludes all directories with the given name, no matter where they are in the directory structure.

Thanks @jhnc, for pointing that out with your comment.

0
jhnc On

Given directory trees:

├── website.com
│   ├── _archive
│   │   └── d1
│   └── d2
│       └── _archive
│           └── d3
└── www

Your command will result in the latter becoming:

└── www
    └── website.com
        ├── _archive
        │   └── d1
        └── d2
            └── _archive
                └── d3

To exclude only the top level _archive directory, you can use the --exclude option, as other answers state, but you also need to provide an anchored path:

--exclude=/website.com/_archive/

giving:

└── www
    └── website.com
        └── d2
            └── _archive
                └── d3

From the manpage:

The matching rules for the pattern argument take several forms:

o  If  a  pattern contains a / (not counting a trailing slash) or a
   "**" (which can match a slash),  then  the  pattern  is  matched
   against  the  full  pathname,  including any leading directories
   within the transfer.  If the pattern  doesn't  contain  a  (non-
   trailing) / or a "**", then it is matched only against the final
   component of the filename or pathname. For  example,  foo  means
   that  the final path component must be "foo" while foo/bar would
   match the last 2 elements of the path (as long as both  elements
   are within the transfer).

o  A  pattern  that  ends  with a / only matches a directory, not a
   regular file, symlink, or device.

o  A pattern that starts with a / is anchored to the start  of  the
   transfer  path  instead  of  the  end.   For example, /foo/** or
   /foo/bar/** match only leading elements in  the  path.   If  the
   rule is read from a per-directory filter file, the transfer path
   being matched will begin at the level of the filter file instead
   of  the  top  of the transfer.  See the section on ANCHORING IN‐
   CLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a
   pattern that matches at the root of the transfer.