Copy a directory and its contents from the command line
To copy a directory and its contents, the general command is:
cp [options] source_directory destination_directory
But the cp command with no options can only be used for copying files, not directories. The common
flags/options for copying directories are:
-
-a,--archive: (best). Copies the directory, recursively copies all content, and preserves symlinks and file attributes. -
-r,-R: (aliases of each other). Copies directories recursively. Does not preserve symlinks or other file attributes.
As always, look at the man pages:
❯ man cp
CP(1) User Commands CP(1)
NAME
cp - copy files and directories
SYNOPSIS
cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
DESCRIPTION
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
Mandatory arguments to long options are mandatory for short op‐
tions too.
-a, --archive
same as -dR --preserve=all
# ...
-d same as --no-dereference --preserve=links
# ...
--preserve[=ATTR_LIST] # note that --preserve=all is valid
preserve the specified attributes
# ...
-R, -r, --recursive
copy directories recursively
# ...
The cp command can create the destination directory
When copying a directory and its contents, cp will create the destination directory if it
doesn’t exist:
~
❯ mkdir foo
~
❯ cp -a foo/ bar
Attempting to copy a directory with cp without setting options
Attempting to copy a directory with cp without setting any options will result in an error:
~
❯ rmdir bar
~
❯ cp foo/ bar
cp: -r not specified; omitting directory 'foo/'
Copy only the contents of a directory
To copy only the contents of a source directory into an existing directory, use a trailing /. or
/* after the source directory path. Note that the destination directory must exist for this to
work:
~
❯ mkdir foo
~
❯ echo "this is a test" > foo/foo.txt
❯ mkdir bar
~
❯ echo "this is another test" > bar/bar.txt
~
❯ cp -a foo/. bar/
~
❯ ls bar
Permissions Size User Date Modified Name
.rw-r--r-- 21 scossar 9 Jan 10:03 bar.txt
.rw-r--r-- 15 scossar 9 Jan 10:02 foo.txt
Additional details
What are file attributes?
File attributes are metadata associated with a file. Things like permissions, file size, ownership, date modified, links (symlinks).
What does the no-dereference flag do?
The --no-dereference flag (shorthand -P when used with cp) in general, causes the utility (in
this case cp) to operate on the symbolic link itself rather than the file or directory it
points to.
When --no-defererence (shorthand -P) is used with cp, when a symbolic link is encountered in the source
directory, cp copies the symbolic link — it creates an identical symlink at the destination —
instead of copying the content of the file that the link points to.
The entry for -P in the cp man page makes this a little clearer:
-P, --no-dereference
never follow symbolic links in SOURCE
What does the preserve=links flag in combination with the no-dereference flag do?
The -d flag is equivalent to --no-dereference --preserve=links. The --preserve=links flag
tells cp to preserve hard links.
The -d flag (or --no-dereference --preserve=links) tells cp to preserve hard links.
Comparing the two when copying a directory that contains hard links (files that were linked with ln instead of ln -s):
-
with just the
--no-dereference(-P) flag, hard link relationships will be broken -
with the
--no-dereference --preserve=linksflags (or the-dflag), hard link relationships will be preserved
I’m not entirely following the how hard links are handled by these options, or even the appropriate
use case for hard links, other than creating them accidentally by using ln without the -s flag.
References
“cp(1) — Linux manual page,” https://man7.org/linux/man-pages/man1/cp.1.html .