Unix Power Tools
Copying Directory Trees with cp -r

Some versions of cp have a -r (recursive) flag.
It copies all the files in a directory
tree -- that is, all the files in a directory and its subdirectories.

The first argument(s) to cp -r can be directory(s) -
or, if you name any file(s), they'll be copied just the way they would
without the -r. The last argument should be a
directory. So, you can use cp -r in two
ways:

Give cp -r directory(s) to copy.
They'll be created as subdirectories of the directory named at the
end.

Give cp -r file(s) to copy. They'll
be copied to the directory named at the end.

Those two
methods are really doing the same thing. They're both copying the
tail of the first pathname(s) to the end of the last pathname.

Here's how to do the copy shown in the figure below. This copies
the directory /home/jane, with all its files and
subdirectories, and creates a subdirectory named jane in
the current directory (.) :

% cd /work/bkup
% cp -r /home/jane .

How can you copy the contents of the subdirectory called
data and all its files (but not the subdirectory itself)
into a duplicate directory named data.bak? First create
the destination directory. That's because the last argument to
cp -r must be a directory that already exists:

% cd /home/jane
% mkdir data.bak
% cp -r data/* data.bak

That doesn't copy any files in data whose names start
with a dot (.).

Figure: Copying /home/jane to Current Directory (/work/bkup) with cp

To copy the subdirectories Sep and
Oct and their files, as well as the file Output, from
the directory /home/jim/calendar into the current directory (.):

% cp -r /home/jim/calendar/[SO]* .

If you use the C shell or bash, you can copy just the directories by using the
handy
curly brace operators:

% cp -r /home/jim/calendar/{Sep,Oct} .

Some gotchas:

Symbolic and hard links are copied as files. That can be good
because, at the destination, a symbolic link might point to the wrong
place. It can be bad if the link pointed to a really big file; the
copy can take a lot of disk space. (In the figure above, notice that
the symbolic link in jane's home directory was converted
to a file named .setup with a copy of the contents of
generic.)

On many UNIXes, the copy will be dated at the time you made the
copy and may have its permissions set by your umask. If you want the
copy to have the original modification time and permissions, add the
-p option.

cp -r will go into an endless loop if you name a
directory in the list to copy from and also as the destination
directory. For example, let's say you're copying everything from the
current directory into an existing subdirectory named
backup, like this:

% cp -r * backup

Unless your cp -r works differently from the ones
I've tried, it will create backup/backup, and
backup/backup/backup, and so on. To avoid that, replace
the * wildcard with other less-"wild"
wildcards. You can also match everything except the destination
directory name by using the ksh ! operator, or the tcsh ^ operator.