## 10.12. Copying Directory Trees with cp -r

cp has a -r (recursive) flag, which copies all the files in a directory tree -- that is, all the files in a directory and its subdirectories.

> NOTE: One of our Unix systems has a cp without a -r option. But it also has an rcp (Section 1.21) command that does have -r. rcp can copy to any machine, not just remote machines. When I need cp -r on that host, I use rcp -r.

cp -r can be used in two ways. The first is much like normal copies; provide a list of files to copy and an existing directory into which to copy them. The -r option just means that source directories will be copied as well as normal files. The second allows you to copy a single directory to another location.

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

  >     % 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 make sure that the destination directory doesn't exist. That's because if the last argument to cp is a directory that already exists, the source directory will be copied to a subdirectory of the destination directory (i.e., it will become data.bak/data rather than just data.bak):

  >     % cd /home/jane
  >     % cp -r data data.bak

- Use this to copy the subdirectories Aug and Sep and their files from the directory /home/jim/calendar into the current directory (.):

  `[..]*` Section 33.2

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

  In many shells, if you wanted the Oct directory too, but not the file named Output, you can copy just the directories by using the handy curly brace operators (Section 28.4):

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

Some gotchas:

- Symbolic and hard links (Section 10.4) are copied as files. That can be a good thing; if a symbolic link were not turned into a file along the way, the new symbolic link would point to the wrong place. It can be bad if the link pointed to a really big file; the copy can take up a lot of disk space that you didn't expect. (In Figure 10-1, 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.) This can be prevented by using the -d option, if your cp supports it.

- 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 may go into an endless loop if you try to copy a directory into itself. 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 is smart enough to scan for files before it starts copying, it will create backup/backup, and backup/backup/backup, and so on. To avoid that, replace the `*` wildcard with other less-"wild" wildcards.

- cp -r doesn't deal well with special files. Most platforms support a -R option instead, which correctly handles device files and the like. GNU cp has -a as a recommended option for normal recursive copying; it combines -R with -d and -p, as described earlier.

Note that directories can be copied to another machine using the same basic syntax with rcp and scp. The only difference is that remote files have `hostname`: in front of them; note that remote files can be used either as source or destination. Relative pathnames for remote files are always relative to your home directory on the remote machine.

>     % scp -r mydata bigserver:backups
>     % scp -r bass:/export/src/gold-20020131 .

scp and rcp use the same syntax; scp uses SSH (Section 46.6) to do its copying, while rcp uses unencrypted connections.

--DJPH and JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.